How to use QCoreApplication::postEvent to inject synthetic input events
-
14-04-2021 - |
Pregunta
I'm injecting Keyboard and Mouse events which are comming over the network into my Qt Application and use QCoreApplication::postEvent
for this. The mouse coordinates are absolute screen pixel coordinates.
QMouseEvent *event = new QMouseEvent(type, QPoint(x, y), mouse_button, mouse_buttons,
Qt::NoModifier);
QCoreApplication::postEvent(g_qtdraw.main.widget, event);
Initially I had just one widget (referenced by g_qtdraw.main.widget
) so I simply used that one as the receiver argument for postEvent
. Now my application has more than one widget and the above code does not do what I want any longer.
A second widget is shown in fullscreen mode and I know that all mouse events have to go to this window but with the above code they are still routed to the main widget.
How do I choose the correct widget as the receiver (the one under the mouse x,y coords)? Is there a standard way, so that Qt chooses the right widget or do I have to track this myself?
Solución
Can you use QApplication::widgetAt()
to find the correct widget at the position and then post to that?
QPoint pos(x, y);
QMouseEvent *event = new QMouseEvent(type, pos, mouse_button, mouse_buttons, Qt::NoModifier);
QWidget *receiver = QApplication::widgetAt(pos);
QCoreApplication::postEvent(receiver, event);
I wouldn't expect that you would have to do this for the key events though. They should be sent to the focused widget (QApplication::focusWidget()
).
Unfortunately, I haven't tested any of this.
Otros consejos
I would suggest posting some code as according to the documentation the signature is:
void QCoreApplication::postEvent ( QObject * receiver, QEvent * event ) [static]
Have you tried giving a pointer to the corresponding QObject
as the receiver
argument?
(edit: note that QWidget
inherits QObject
)
Here is the Answer that was added to the Question:
I now use the following which works fine (Many thanks to Dusty Campbell):
QPoint pos(x, y); QWidget *receiver = QApplication::widgetAt(pos); if (receiver) { QMouseEvent *event = new QMouseEvent(type, receiver->mapFromGlobal(pos), mouse_button, mouse_buttons, Qt::NoModifier); QCoreApplication::postEvent(receiver, event); }