2

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!

Baxtrax
  • 75
  • 5
  • I don't have a solution in mind, just some comments: How do you receive the keys on the main window? Do you use an event filter? As far as I understand, that's the intended way to achieve receiving key events. If you do use event filters, do you accept the events? If not maybe try that. You also check who receives the events first, by stepping through the code (use the Qt sources and set breakpoints on where the main window and Qt3D handle key events. Another solution that pops to my mind is to use [my implementation of a Qt3D widget](https://github.com/florianblume/qt3d-widget). – Florian Blume Mar 12 '21 at 13:20
  • Because maybe `createWindowContainer` and embedding Qt windows this way causes these issues. Unfortunately, you need at least Qt 5.14 for the widget to work because it needs to get the GLuint of a Qt3D texture which is only available from this version on. – Florian Blume Mar 12 '21 at 13:20
  • As for your last question, have you tried disabling the Qt3DWindow? Maybe `createWindowContainer` doesn't propagate the `enabled` proprety. Sorry I can't provide a full solution but maybe we can get there together. – Florian Blume Mar 12 '21 at 13:23
  • No its ok if you cant, just wanted to see if I can get some helping figuring this problem out! I wish the documentation supplied more information on createWindowContainer as it does a lot of stuff that doesn't seem to be supplied in the documentation. – Baxtrax Mar 13 '21 at 03:20
  • Funnily enough I actually looked into using your implementation as it would make things a lot easier, I just wanted to see if this could be solved before I move over as it seems like a lot of people could run into this problem. – Baxtrax Mar 13 '21 at 03:21
  • I have tried disabling the window but I cant get access to it (at least in the constructor) because it is created at runtime. I could run a loop that fetches the object once the program has started but that seems a little too much just for a 3D window. I will probably end up using your implementation as a work around as it is a quick and easy solution. I'll keep this thread updated if I end up doing so. – Baxtrax Mar 13 '21 at 03:24
  • And as a another note, I do not use a event filter, I am overriding `keyReleaseEvent` and `keyPressEvent` in the MainWindow to process their respective events. Is using eventFilters a way of grabbing global Events or does it only grab events of the currently focused widget. At least from my testing, it seems that the Qt3DWindow is grabbing focus and taking the keypresses for its self. – Baxtrax Mar 13 '21 at 03:28
  • I will add more information on how I catching and process events to the post to help clarify. – Baxtrax Mar 13 '21 at 03:29
  • I'm not too familiar with event filters but there are some [docs](https://doc.qt.io/qt-5/eventsandfilters.html) for them. My suggestion would also be to set breakpoints in Qt3DWindow and QWindow (or QWidget depending on what your "root" windows is) and see who receives events first. If it's you root window, try to install an event filter there that accepts the key press events so that they don't travel on to the Qt3DWindow. – Florian Blume Mar 13 '21 at 08:15
  • I just tried an example with embedding a `QWindow` using `createWindowContainer` and there you don't receive any key events either, so `createWindowContainer` seems to be the issue here. – Florian Blume Mar 13 '21 at 08:47

1 Answers1

1

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!

Baxtrax
  • 75
  • 5