How to use QCoreApplication::postEvent to inject synthetic input events
Asked Answered
C

3

10

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?

Celluloid answered 4/1, 2012 at 15:38 Comment(1)
Please place answers in Answer blocks. Later, you can accept your own Answer. Also see How does accepting an answer work?Amiss
P
11

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.

Parquet answered 5/1, 2012 at 8:3 Comment(1)
Thanks, I got it to work using your hint. I also had to use receiver->mapFromGlobal(pos) in order for the coordinates to be correct.Celluloid
P
3

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)

Pheni answered 4/1, 2012 at 22:24 Comment(2)
I've added new info. When I have more than one window/widget, how do I choose the right one (the one under mouse x,y)?Celluloid
Ah, you missed out the key information on how you wanted to decide the widget ;)Pheni
A
1

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);
}
Amiss answered 17/12, 2019 at 17:51 Comment(1)
@Celluloid - If you add your answer as an Answer in a block, then please let me know so I can delete this. We still don't have a way to assign an answer to the OP for situations like these.Amiss

© 2022 - 2024 — McMap. All rights reserved.