Hermandroid
Hermandroid

Reputation: 2200

Post events without specifying target object in Qt

I need help to understand to use QEvents in QT, this is driving me crazy.

I am writting an application using custom events, but as in QApplication::postEvent function, it's necesary to specify the target object.

As I understand, it's possible to post events to Qt's event loop with

QApplication::postEvent(obj_target, QEvent myevent);

This means that I'm trying to catch "myevent" event in obj_target an do some stuff.

But I need to post events without specify a target object, as QMouseEvent or QKeyEvent do

I'm really confused, it's possible to post an event without specifying a target object?

Thank you very much in advance

Upvotes: 7

Views: 6735

Answers (2)

galinette
galinette

Reputation: 9292

For this purpose, I have a specific singleton class which I call GuiSignalHub. It regroups all the application-wide signals.

Objects that want to trigger an application-level action (such as opening context help) just connect their signal to the GuiSignalHub signal. Receivers just connect the GuiSignalHub to their slot.

Upvotes: 1

There is no trivial way to post events "globally", as Dan has said. All of the event dispatching of native events is done by private Qt implementation code.

The important distinction is:

  1. There are native messages/events, delivered by the operating system, usually received by a window-specific event loop.

  2. There are QEvents.

Internally, Qt keeps track of the top-level Widgets (windows, really), so when it receives an event from the OS, it knows which window it should go to - it can match it using the platform window id, for example.

QEvent delivery makes no sense without a receiving object, since sending an event to an object really only means that QObject::event(QEvent*) method is called on that object. It's impossible to call this method without having an object instance!

If you want to synthesize a global key press or mouse click event, then you have to figure out what object the event goes to. Namely:

  1. Identify what top-level window (widget) the event should go to. You can enumerate top level widgets via qApp->topLevelWidgets().

  2. Identify the child widget the event should go to. If it's a keyboard event, then sending the event to currently focused widget via qApp->focusWidget() is sufficient. You need to enumerate the child widgets to find the deepest one in the tree that overlaps the mouse coordinates.

  3. Send the correct QEvent subclass to the widget you've just identified. Events delivered to top-level widgets will be routed to the correct child widget.

When sending mouse events, you also need to synthesize relevant enter and leave events, or you risk leaving the widgets in an invalid state. The application.cpp source file should give you some ideas there.

This doesn't give you access to native graphical items, such as menus on OS X.

Please tell us exactly what you're trying to do. Why do you want to post a broadcast event? Who receives it? Since your own QObject-derived classes will receive those broadcasts, I presume, it's easy enough to use signal-slot mechanism. You'd simply connect(...) those receiver classes to some global broadcaster QObject's signal(s).

Upvotes: 2

Related Questions