需要 Qt3DWindow 忽略键盘事件

Need Qt3DWindow to ignore keyboard events

我有一个程序可以在 mainwindow 中接受键盘输入并用它做一些事情,所以它已经在那里得到处理了。作为上下文:mainwindow 在一堆输入显示旁边有一个 Qt3DWindow 小部件,这些输入显示会在按下键盘按钮时发生变化。

该程序按预期工作并且正在主程序中处理 keyEventswindow 直到用户开始与 Qt3DWindow 交互并使用鼠标移动它(我在那里有一个 OrbitCameraController,所以你可以四处看看)。一旦发生这种情况,window 似乎会带走 MouseEvents 和 KeyEvents。因此,如果在单击 Qt3DWindow 后按下某个键,则 mainwindow 不会检测到该事件并且不执行任何操作。如果您只需在 Qt3DWindow 小部件之外单击,一切都会恢复正常

TLDR:

我的期望: 我希望即使用户使用鼠标与 Qt3DWindow 交互并环顾四周,他们仍然可以使用键盘并且输入显示仍然可以在 Qt3DWindow 小部件之外工作。

发生了什么: KeyEvents 不再传递到 mainwindow 并且在再次单击 mainwindow 之前输入显示不起作用。

我试过的: 这是上下文的代码,因为这是制作最终小部件然后将其添加到应用程序布局的地方。图我在添加之前在此处修改了小部件,因此它不需要 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 的 none 甚至接近于接触 Qt3DWindow,因为我将重构并将 Qt3D 的东西移动到它自己的 class 稍后。

更新:

为了帮助清理一些信息,我将我的 KeyEvents 处理为 MainWindow 的覆盖函数(如果我理解它是如何正确调用的),如下所示:

mainwindow.h

protected:
    void keyPressEvent(QKeyEvent* event);
    void keyReleaseEvent(QKeyEvent* event);

mainwindow.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's implementation of Qt3D widget,因为它似乎可以解决我 运行 遇到的所有问题。我强烈推荐使用它,因为它在设置 Qt 3D Window 时简化了很多艰苦的工作,而且真的很有帮助!不过,我宁愿将 Florian Blume 的评论标记为答案。因为他比我更名副其实!