Need Qt3DWindow to ignore keyboard events

I have a program the takes keyboard input in the mainwindow and does some stuff with it, so it is already getting handled there. As context: The mainwindow has a Qt3DWindow widget next to a bunch of input displays that change when keyboard buttons are pressed.

The program works as expected and keyEvents are being processed in the mainwindow until the user goes to interact with the Qt3DWindow and move it around with their mouse(I have an OrbitCameraController there so you can look around). Once this happens, the window seems to take MouseEvents AND KeyEvents with it. So if a key is pressed after the Qt3DWindow is clicked, then mainwindow doesnt detect the event and does nothing. Everything goes back to normal if you just click outside of the Qt3DWindow widget

TLDR:

What I expect: I expect that even if the user interacts with the Qt3DWindow with the mouse and looks around, they can still use the keyboard and the input displays will still work outside the Qt3DWindow widget.

What happens: KeyEvents are no longer passed into the mainwindow and input displays do not work until mainwindow is clicked again.

What I have tried: Here is the code the for context, as this is where the final widget is made then added to a layout on the application. Figure I modify the widget here before its added so it doesn’t take 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);

I have tried modifying container so it has NoFocus policy — I assumed it may just be that the Qt3DWindow widget is just taking focus and setting the focus policy to NoFocus would at least make it so it couldn’t be interacted with. Attempt 1:

QWidget *container = QWidget::createWindowContainer(view);
container->setFocusPolicy(Qt::NoFocus);
ui->simulation_Frame->layout()->addWidget(container);

I have tried modifying container so it has setEnabled(false) — I know this disables all input but I just wanted to see if I could modify the container at all. Attempt 2:

QWidget *container = QWidget::createWindowContainer(view);
container->setEnabled(false);
ui->simulation_Frame->layout()->addWidget(container);

It seems I cant modify the widget what so ever! Anything I do, the widget still is able to be interacted with and nothing changes. Its as if I’m modifying the wrong widget or something. IF anyone needs anymore information I can supply it, this is a part of a big project but none of the code atm even gets close to touching the Qt3DWindow, as the I will be refactoring and moving Qt3D stuff into its own class later.

UPDATE:

To help clear up some information I process my KeyEvents as an overidden function (if I understand how its called correctly) of MainWindow as shown below:

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
        }
    }
}

If this is the incorrect way of dealing with keyboard inputs please let me know!

Answer

I have decided to use Florian Blume‘s implementation of Qt3D widget as it seems to solve all problems I have run into. I would highly recommend using it as it simplifies a lot of the hard work when setting up a Qt 3D Window and is really helpful! I would rather mark Florian Blume’s comment on it as an answer though. As he deserves the reputation more then I do!

Leave a Reply

Your email address will not be published. Required fields are marked *