Emulate a global keypress in Qt - c++

I am building a Qt Application for a raspberry pi, which is connected to a rotary encoder. When the user presses the rotary encoder button, the application registers the hardware interrupt from the button and emits a signal which the application can intercept.
The challenge is that the application has multiple windows that can be displayed, and I would like to simply have a function which translates the button press signal into a global key press that can be registered by any active window in the application, without having to add extra logic to determine which window is active to send the key press directly to it. Is there a way to simulate a system-wide key press so that whatever window is in focus will get it?
So far, I have the following snippet of code, though it requires a reference to a specific QObject to direct the keypress to:
QKeyEvent *event = new QKeyEvent(QEvent::KeyPress, Qt::Key_Enter);
QCoreApplication::postEvent (receiver, event);
where receiver is the object to direct the keypress too. Any ideas?

To broadcast a key event to all top-level widgets (i.e. windows):
for(auto w : qApp->allWidgets())
{
if(w->isTopLevel())
{
qApp->postEvent(w, new QKeyEvent(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier));
}
}
To directly send the event to the active window (the foremost one):
qApp->postEvent(qApp->activeWindow(), new QKeyEvent(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier));

Related

What signal can Qt Widget catch from Virtual Desktop?

I have a C++ app which pops up a QDockWidget. I want this widget to close when the user clicks outside the widget, and have achieved this using the eventFilter() to catch the event QEvent::WindowDeactivate, and call Hide().
I also need the QDockWidget to close when the user changes desktop - and this doesn't require a mouse click. (Windows virtual desktop).
I've looked for some other appropriately named QEvent but no luck. My QDockWidget allows user input via keyboard, so I can't use keyboard focus for hiding.
What signal or event could I watch for to Hide() when a user changes windows desktop?

How can I get Key press in MFC App when the app is inactive

I create an app using MFC Framework that auto hide on startup, and if I press SHIFT+W then it shows the Windows.
I inherited the function PreTranslateMessage() like that:
BOOL CTestAppDlg::PreTranslateMessage(MSG* pMsg){
if (pMsg->message == WM_KEYDOWN){
if (pMsg->wParam == 0x57){
if (GetKeyState(VK_SHIFT) & 0x8000) {
ShowWindow(SW_SHOW);
}
}
}
return CDialog::PreTranslateMessage(pMsg);
}
But this function only catches the keypresses if MFC App is active. So if this App is hide in OnPaint() function with ShowWindow(SW_HIDE) then it cannot catch the SHIFT+W to show windows normally. How can I do for it? Thank all
As explained under Keyboard Focus and Activation:
The system posts keyboard messages to the message queue of the foreground thread that created the window with the keyboard focus.
As a window gets hidden the system transfers keyboard focus to the next eligible window, causing your window to no longer receive keyboard input as you observed.
There are several ways to observe input globally. In this case the most appropriate solution is to just call RegisterHotKey and provide a CWnd::OnHotKey implementation for the respective receiver of the WM_HOTKEY message.

Qt/QML: How to activate a Shortcut from C++?

I have an application which receives input from a serial port and interprets them as key events. The key events are created in C++ and sent to QGuiApplication::focusWindow() with qApp->sendEvent.
The GUI is implemented in QML and has been handling input through key event handlers. I would like to start using the Shortcut QML class to handle cases where I want behavior regardless of which object has focus.
I've discovered that Shortcuts which respond to a real keyboard will not respond to qApp->sendEvent, nor do they respond to qApp->postEvent.
Getting the behavior I want to reliably occur without Shortcut would be a real pain - is there I way I can handle my synthetic events which will make them visible to Shortcut?
Qt shortcut objects work through parts of the Qt system which are not part of the regular API, but are exposed to QPA. Specifically, QWindowSystemInterface::handleShortcutEvent, which takes as arguments the current focus window and most of the information encapsulated in a QKeyEvent.
// A helper to send a QKeyEvent to shortcuts
bool handleShortcutEvent(const QKeyEvent &ev, QWindow *focusWindow) {
return QWindowSystemInterface::handleShortcutEvent(focusWindow, ev.timestamp(), ev.key(), ev.modifiers(), ev.nativeScanCode(), ev.nativeVirtualKey(), ev.nativeModifiers(), ev.text(), ev.isAutoRepeat(), ev.count());
}
// in my key event generating function
if(!handleShortcutEvent(event, focusWindow))
qApp->sendEvent(focusWindow, &event);

How to send XInput button?

I want to send a button pressed signal to a game and I have read the APIs in MSDN.
But the APIs there only provide functions which get gamepad state not send signal to PC.
Can any one help me?
There is no API for sending a button pressed signal. You will have to write code that monitors the gamepad state every frame and when a button press is detected you send the signal. (Note: You detect the button press by checking the current button flag against the previous frames button flag. If they differ the button has either been pressed or released, depending on flag state.)
A few more details here: Which event to listen for during XInput events

QtQuick key press event propagation

I have Qt GUI application. Main window contains QtQuick component which placed on it using window container:
QQuickView * view = new QQuickView ();
QWidget * container = QWidget::createWindowContainer (view, this);
I'd like to handle all key press events under whole window. But I faced with problem that I can't handle key events when focus acquired by QtQuick component even if I've set the window as parent for it.
The documentation say that such behaviour is expected:
QWidget *QWidget::createWindowContainer(QWindow *window, QWidget *parent = > Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags())
...
The window container has a number of known limitations:
...
Focus Handling; It is possible to let the window container instance have any focus policy and it will delegate focus to the window via a call to QWindow::requestActivate(). However, returning to the normal focus chain from the QWindow instance will be up to the QWindow instance implementation itself. For instance, when entering a Qt Quick based window with tab focus, it is quite likely that further tab presses will only cycle inside the QML application. Also, whether QWindow::requestActivate() actually gives the window focus, is platform dependent.
My question is: is there way to handle key press event under whole window even if focus is acquired by QtQuick component?
Minimal and complete example available at GitLab.
One possible (but ugly) solution is:
Handle key press event in QML;
Notify C++ code from QML by signal;
In C++ code generate key press event;
Handle native event and regenerated event in common event filter.
Example available at GitLab.