Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct
QKevEvent to a minimized QQuickWindow
The code snippets below (possibly the syntax is incorrect) implement an app which runs a QML script to generate a GUI:
QApplication *app = new QApplication(argc, argv);
QQmlApplicationEngine *appEngine3 = new QQmlApplicationEngine(this);
This does its job, the GUI is shown and can be controlled with the keyboard.
There's a timer which expires periodically. When it expires, 'eventTimerExpired' is called and it must send a QKeyEvent to the QML app:
QKeyEvent *ev1 = new QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier);
QKeyEvent *ev2 = new QKeyEvent(QEvent::KeyRelease, Qt::Key_Down, Qt::NoModifier);
QCoreApplication::postEvent(appEngine3->rootObjects().first(), ev1); QCoreApplication::postEvent(appEngine3->rootObjects().first(), ev2);
My issue is with the above. If the window has the focus, everything is okay, as the QKeyEvent is transferred to the main QML object, which processes it and moves the cursor downwards in the GUI. The problem occurs when I minimize the QML window, it loses the focus and no longer receives the QKeyEvent, however QKeyEvents are still periodically emitted.
How can I make minimized/focusless QML Qt objects also process/accept QKeyEvents?
I'd rather use signal/slots directly so you're not dependent on your application having the focus.
I haven't found any slot in QQmlApplicationEngine and QQuickWindow which would fit my needs...
But QQuickWindow has a method called keyPressEvent. Unfortunately it's protected, so I can't call it...
No matter if I send the QKeyEvent either to QQmlApplicationEngine or QQuickWindow instance, it never gets processed by the QML script itself. I fear the event handler in a deeply embedded class simply filters out my QKeyEvents saying 'the window has no focus'.
What I was suggesting is that you create a slot that you would connect to your timer timeOut signal
I'd like to apologize for my dummy questions (I'm rather beginner when it comes to Qt) in advance.
Maybe you're mislead by my code. The timer's only purpose is to automatically generate keyboard events without the user's intervention, so the QML app receives events even if it has no focus. It has only testing purposes.
Furthermore, I've missed to share a possible important detail. Before the first rendering the beforeRendering() signal is caught, and I install a custom frame buffer object, so that the entire QML page is rendered into that instead of the window. This way the window is black, but my FBO has the pixel data and this is exactly what I need. Then I programmatically minimize the black window, and send those QKeyEvents to my QML to have the cursor move. The FBO shows the pixel data with a steady cursor; the cursor's position only changes if the window has focus, e.g. it is unminimized.
Would you be so kind and help me out with my issue with a little more detail? How can I make the QQmlApplicationEngine/QQuickWindow process my QKeyEvents even if its window has no focus?
To me it appears that QQmlApplicationEngine/QQuickWindow filters only QKeyEvents out if it has no focus; this impies that I could use other events. In theory it would be alright; my problem is that I definitely have to send cursor movement events (and other keyboard events), and to achieve this, I would have to convert my custom events to QKeyEvents, pass those events to QQmlApplication/QQuickWindow, which would filter it out... (if I'm right)
Or shall I implement an own event processing loop in QQmlApplicationEngine/QQuickWindow?
What cursor is it ? The mouse cursor ?
A guy at the company has created a sample QML which has a menu on the right side. By pressing the arrow keys the cursor moves up and down in the menu. Cursor == selection == highlighted menu entry... you know what I mean ;)
Again, to simplify things I'd add one or two slot dedicated to moving the arrow up and down in your menu, so you don't need to do anything funky to try to send keyboard related events to an unfocused application.
I don't understand how this solves my issue.
Anyway, I'm going to try to modify Qt sources (I use a locally compiled Qt), so that QQuickWindow::keyPressEvent and keyReleaseEvent are not proctected, but public, so that hopefully I'll be able to send them the intended keyboard events...
A moveDown slot is easier to connect to and doesn't depend on the focus stat of your application. You also don't need to fiddle with Qt's sources. On that them you can subclass QAbstractEventDispatcher if you really want to but that's just overkill for the functionality you are seeking.