c++ - 需要 Qt3DWindow 来忽略键盘事件
问题描述
我有一个程序在主窗口中接受键盘输入并用它做一些事情,所以它已经在那里处理了。作为上下文:主窗口在一堆输入显示旁边有一个 Qt3DWindow 小部件,当按下键盘按钮时,这些小部件会发生变化。
该程序按预期工作,并且 keyEvents 正在主窗口中处理,直到用户与 Qt3DWindow 交互并用鼠标移动它(我在那里有一个 OrbitCameraController,所以你可以环顾四周)。一旦发生这种情况,窗口似乎会带上 MouseEvents 和 KeyEvents。因此,如果在单击 Qt3DWindow 后按下某个键,则 mainwindow 不会检测到该事件并且什么也不做。如果您只是在 Qt3DWindow 小部件之外单击,一切都会恢复正常
TLDR:
我 的期望:我希望即使用户使用鼠标与 Qt3DWindow 交互并环顾四周,他们仍然可以使用键盘并且输入显示仍然可以在 Qt3DWindow 小部件之外工作。
会发生什么: KeyEvent 不再传递到主窗口,并且输入显示在再次单击主窗口之前不起作用。
我尝试过的: 这是 for 上下文的代码,因为这是制作最终小部件的地方,然后将其添加到应用程序的布局中。图我在添加之前在此处修改了小部件,因此它不需要 keyEvents。
//More view and scene configuration above...
view->setRootEntity(scene);
view->defaultFrameGraph()->setClearColor(QColor(QRgb(0x05050f)));
//Create the widget based off the Qt3DWindow
QWidget *container = QWidget::createWindowContainer(view);
//Add widget to layout in mainwindow
ui->simulation_Frame->layout()->addWidget(container);
我已经尝试修改容器,使其具有 NoFocus 策略——我认为可能只是 Qt3DWindow 小部件正在获取焦点,并且将焦点策略设置为 NoFocus 至少会使其无法与之交互。尝试1:
QWidget *container = QWidget::createWindowContainer(view);
container->setFocusPolicy(Qt::NoFocus);
ui->simulation_Frame->layout()->addWidget(container);
我尝试修改容器,使其具有 setEnabled(false) - 我知道这会禁用所有输入,但我只是想看看我是否可以修改容器。尝试2:
QWidget *container = QWidget::createWindowContainer(view);
container->setEnabled(false);
ui->simulation_Frame->layout()->addWidget(container);
看来我无法修改小部件!无论我做什么,小部件仍然能够与之交互并且没有任何变化。好像我正在修改错误的小部件或其他东西。如果有人需要更多信息,我可以提供,这是一个大项目的一部分,但代码 atm 甚至都没有接近 Qt3DWindow,因为稍后我将重构 Qt3D 并将其移动到它自己的类中。
更新:
为了帮助清除一些信息,我将 KeyEvents 处理为 MainWindow 的覆盖函数(如果我理解它是如何正确调用的),如下所示:
主窗口.h
protected:
void keyPressEvent(QKeyEvent* event);
void keyReleaseEvent(QKeyEvent* event);
主窗口.cpp
void MainWindow::keyPressEvent(QKeyEvent *event) {
//Only process keyPressEvents that are not repeating. (ie. Inital press)
if (event->isAutoRepeat() == false)
{
switch(event->key())
{
case Qt::Key_W:
// emit a signal when button has changed, which is tied to other
// classes slots for updating input displays
emit keyboard_WChanged(true);
qDebug() << "Keyboard W" << true;
break;
case Qt::Key_S:
emit keyboard_SChanged(true);
qDebug() << "Keyboard S" << true;
break;
//etc... more cases for each key
}
}
}
void MainWindow::keyReleaseEvent(QKeyEvent *event) {
// This may not be needed for release event but never removed it lol!
// Still works though.
if (event->isAutoRepeat() == false)
{
switch(event->key())
{
case Qt::Key_W:
// emit a signal when button has changed, which is tied to other
// classes slots for updating input displays
emit keyboard_WChanged(false);
qDebug() << "Keyboard W" << false;
break;
case Qt::Key_S:
emit keyboard_SChanged(false);
qDebug() << "Keyboard S" << false;
break;
//etc... more cases for each key
}
}
}
如果这是处理键盘输入的错误方式,请告诉我!
解决方案
我决定使用Florian Blume的Qt3D 小部件实现,因为它似乎解决了我遇到的所有问题。我强烈推荐使用它,因为它在设置 Qt 3D 窗口时简化了很多繁重的工作,而且真的很有帮助!不过,我宁愿将 Florian Blume 对此的评论标记为答案。因为他比我更值得享有声誉!
推荐阅读
- java - Apache http 客户端 4.5 表单身份验证失败返回相同的登录页面
- kotlin - 获取 kotlin 密封的类名层次结构
- android - 导入 Sceneform 资产后构建未运行,模型未显示在查看器中
- python - 如何构建 numpy 二维数组的直方图
- ionic-framework - 通过 Ionic App 的 Openfire XMPP 客户端连接
- node.js - VS Code Run 扩展 - 运行程序没有显示输出
- amazon-cognito - Svelte/汇总错误“缺少全局变量名”
- wso2 - 使用 WSO2 Enterprise Integrator 存储代币的最佳方式
- google-apps-script - 使用 Google 应用脚本将文本替换为超链接
- mysql - 如何从具有相同 ID 的帖子中获得最低价值