How to monitor QT signals? - c++

During debugging, I want to see what's awaits my program's event loop.
It's probably flooded, and I want to see by what signals, without (manually) adding specific log-message to every Q_EMIT.
Possible solutions might be watching some internal-qt-data structure that contains the events-queue (Is there such thing? how?)
Or -
Write a log message for every signal emitted (Is that possible?).
Any other ideas?
(QT 4.8 on Windows, using visual studio 2012)

Signals and events are two things that don't have anything to do with each other.
I want to see what's awaits my program's event loop. It's probably flooded.
First of all, let's get the nomenclature straight:
an event queue is where events are stored until delivery;
an event loop is what drains the event queue and delivers events to QObjects,
an event flood happens when, on average, during the delivery of each event there is more than one event added to the queue.
There are two reasons only why an event queue might get flooded:
It takes too long to process some events (e.g. when your code blocks): the drain rate of the queue is lower than the fill rate due to timing.
You're adding more than one event per each event delivered (on average): the fill rate of the queue is higher than the drain rate due to event multiplication - this is completely unrelated to any timing. An apt name for it would be an event storm.
To detect code the blocks for too long, you can use a tool I wrote for another answer.
To know how many events are waiting for any given thread, use the undocumented qGlobalPostedEventsCount(). You add that to the code of the tool linked-to above.

Not sure if this is sufficient for you but you can try installing event filters in between QObjects that implement eventFilter() like this:
class MyWidget : public QWidget
{
QGraphicsView myView;
MyWidget()
{
myView->installEventFilter(this);
// incoming events to myView are shown on the standard output
}
};
You can get more creative with this reading the docs.

The Qt documentation for Events and Filters states:
It is also possible to filter all events for the entire application, by installing an event filter on the QApplication or QCoreApplication object. Such global event filters are called before the object-specific filters. This is very powerful, but it also slows down event delivery of every single event in the entire application.
Therefore, you can create an event filter on the QApplication or QCoreApplication and monitor all events, checking their type.
Alternatively, QCoreApplication uses the virtual notify function to deliver events to objects. Overriding QCoreApplication would allow you to see both the event and QObject to which the event will initially* be delivered.
*Note that events are propagated to parent objects, if the receiving object ignores the event.
If you choose to use notify, be aware of the future direction for this function:
Future direction: This function will not be called for objects that live outside the main thread in Qt 6. Applications that need that functionality should find other solutions for their event inspection needs in the meantime. The change may be extended to the main thread, causing this function to be deprecated.

Related

invoke code after all queued events are processed

I have two functions: myCode1() and myCode2(). I have very little control over what is in myCode1() (will be implemented by other party), it can be almost anything, within some sane limits, of course. I need to call first myCode1() and only after it is "finished" I need to call myCode2(), which implementation I have in full control. By "finished" I mean when all synchronous code is done and event loop is done processing all events which were created as the result of myCode1().
My first try was trivial:
myCode1();
myCode2();
But there is a trouble that when myCode1() opens dialog with its own event loop (QDialog::exec()), then myCode2() is called only after the dialog is closed, which is not what I need. I need to call myCode2() after the dialog gets open and is waiting for users interaction.
So my second try:
QTimer::singleShot(0, []{ myCode2(); });
myCode1();
This is slightly better because it schedules myCode2() to be processed by event loop after myCode1() does its synchronous work, i.e. after the potential dialog with blocking event loop gets opened.
But there is yet another problem. myCode1() can create lots of posted events in event queue and I need them to be processed before actually before calling myCode2(). But with the way show above, these events are queued after scheduled myCode2().
So what I would actually need is to schedule myCode2 after ALL events are done including posted events, i.e. when the event loop is empty. And it should work also in the presence of blocking dialogs etc.
I also tried QCoreApplication::processEvents() but these events can post more events and enqueue them at the end of the queue... Moreover QCodeApplication::hasPendingEvents() is marked as deprecated so it cannot help to check whether event queue is empty. Otherwise my implementation would look like this:
void myCode2()
{
while (QCoreApplication::hasPendingEvents())
{
QCoreApplication::sendPostedEvents();
QCoreApplication::processEvents();
}
doMyCode2(); // this would do the actual code
}
And I would schedule it with the QTimer as above. But as I wrote, hasPendingEvents() is deprecated... so I am in bad luck.
Any ideas how to achieve what I need to achieve? I hope there is some simple solution which I just overlooked.
PS: To clarify the purpose - myCode2() should inform about the state of the application. And I need to inform about "final" or "stable" state. Which means that if there are yet more events to be processed, the state is not finished nor stable. Therefore I need to process all events first, including events which were created by previous events.

Event Queue in Qt

How many event queues are there in Qt application? Events like click etc are enqueued in the queue. And you can also enque events using function like postEvent. Are all these events in the same queue? if yes is there a way to define different queues?
Normally, there is at most one event queue per each thread.
It is possible to have additional event queues, with two implementation strategies that differ on whether you remain compatible with QCoreApplication::postEvent.
If you don't care about QCoreApplication::postEvent working with your queue, everything is up to you. You can implement the queue in whatever way you wish. Note that Qt doesn't implement a way of marking a QObject as belonging to a particular event queue. When you're ready to deliver the events from your queue, you simply invoke QCoreApplication::notify, passing it the target object pointer, and event pointer. Easy-peasy. You don't have any control over the events that are delivered to any and all objects from the default queue, of course.
Another way is to remain compatible with QCoreApplication::postEvent. Namely, you somehow "mark" an object as having its events handled by your queue. You intercept the event about to be delivered to the target, enqueue it, and handle it yourself as needed.
This is the QStateMachine-like hack. It is good. And bad. And things in between. It's worth knowing how it's done and why.
Hierarchical state machines typically need to control the delivery of events and inject their own events into the queue, in front of other events. This is so that the state transition events are delivered in right order in relation to the events that cause the transitions; furthermore sometimes a transition-causing event might need to be delivered multiple times, retained for later delivery, etc.
This is all in the face of the rigid event lifetime enforced by the default event dispatching system. To work around it, QStateMachine implements its own event queue. Whenever you declare a transition on an event that would be delivered to some object, the state machine installs itself as an event filter on that object.
Then, whenever the original event reaches the target object, the filter intercepts the event and prevents its delivery to the target object. Now it must make a copy of the event, and insert it into its own queue. The copy must be made, because the event will be deleted by the event dispatcher as soon as the control leaves the event filter and/or the target object's event() method.
Unfortunately, before Qt 6, QEvents were not cloneable - at least not publicly so. There was some clone functionality hidden in Qt's innards, usable by user code, but it was a private API, and not based on the virtual copy constructor idiom.
Qt 6 has added the QEvent::clone method, and events should be presumed cloneable. Custom events in legacy code that wasn’t ported to Qt 6 won’t support this, and their clones will not be fully functional if they carry data.
Using the filter-based idiom/hack, you can implement a notion of a QObject belonging to a certain event queue. When your queue filters the events on the target object, clones them, and enqueues them for separate delivery, the object functionally resides on your event queue. When no such filtering takes place, the object resides on the default per-thread queue. You can also only intercept events of the type(s) your queue is interested in, just like the QStateMachine does.

Qt GUI event recording and playback

I'm attempting to implement a simple, lightweight system for recording Qt GUI events and playing them back from a script. I thought this would be fairly straightforward using the magic of Qt's event system, but I'm running into a problem I don't understand.
Here's quick summary of what I'm doing:
RECORDING:
I use QApplication.instance().eventFilter() to capture all GUI events I'm interested in* and save them to a Python script, in which each step looks something like this:
obj = get_named_object('MainWindow.my_menubar')
recorded_event = QMouseEvent(2, PyQt4.QtCore.QPoint(45, 8), 1, Qt.MouseButtons(0x1), Qt.KeyboardModifiers(0x0))
post_event(obj, recorded_event)
PLAYBACK:
I simply execute the script above, in a worker (non-GUI) thread. (I can't use the GUI thread because I want to keep sending scripted events to the application, even if the 'main' eventloop is blocked while a modal dialog eventloop is running.)
The important stuff happens in my post_event() function, which needs to do two things:
First, call QApplication.postEvent(obj, recorded_event)
Wait for all events to finish processing:**
Post a special event to the same eventloop that obj is running in.
When the special event is handled:
Call QApplication.processEvents()
Set a flag that tells the playback thread it's okay to continue
After the second part is complete, my expectation is that all effects of the first part (the recorded event) have completed, since the special event was queued after the recorded event.
The whole system mostly seems to work just fine for mouse events, key events, etc. But I'm having a problem with QAction handlers when I attempt to playback events for my main QMenuBar.
No matter what I try, it seems that I can't force my playback thread to block for the completion of all QAction.triggered handlers that result from clicking on my QMenu items. As far as I can tell, QApplication.processEvents() is returning before the QAction handler is complete.
Is there something special about QMenu widgets or QAction signals that breaks the normal rules for QApplication.postEvent() and/or QApplication.processEvents()? I need a way to block for the completion of my QMenu's QAction handlers.
[*] Not every event is recorded. I only record spontaneous() events, and I also filter out a few other types (e.g. Paint events and ordinary mouse movements).
[**] This is important because the next event in the script might refer to a widget that was created by the previous event.
I think your problem might best be served by using QFuture and QFutureWatcher (that is, if you're using the QtConcurrent namespace for threads, and not QThreads). Basically, the Qt Event handling system does NOT necessarily handle events in the order they're posted. If you need to block until a certain action is completed, and you're doing that action in a separate thread, you can use the QFuture object returned by QtConcurrent::run() with a QFutureWatcher to block until that particular thread finishes its processing.
Something else to consider is the way you handle events. When you use QApplication.postEvent(), the event you create gets added to the receiver's event queue to be handled later. Behind the scenes, Qt can reorder and compress these events to save processor time. I suspect this is more your problem.
In your function which handles playback, consider using QCoreApplication::processEvents(), which will not return until all events have finished processing. Documentation for QCoreApplication is here.
QMenu widgets and QAction signals are a special case. QMenu has an exec() function, normally used for popups. I suspect (but I don't know for sure) that QMenuBar would use this mechanism when it opens a regular pull-down menu. The docs are not clear about this, but Menus act a lot like dialog boxes in that they block all other user activity - how would Qt do this except by giving menus their own event loop? I can't fill in all the blanks from the information in your post, but I don't see how your playback thread would cope with a new event loop.

QT Event Problem

I am writing a qt program and have the following requirement.
When 30 sec passed without any click, lock the screen. If someone clicks again after these 30 secs, redirect him to a login screen.
I have read the qt doc about event and I believe that I need either method 1 or 2 to process mouse event.
1.Installing an event filter on qApp
An event filter on qApp monitors all events sent to all objects in the application.
2.Reimplementing QApplication::notify().
Qt's event loop and sendEvent() call this function to dispatch events. By reimplementing it, you get to see events before anybody else.
They also seems powerful to me, but I don't understand their difference.
Which one suits my requirement? Thank You.
You can basically achieve the same thing with either solution except for the fact that QApplication::notify (or its override) will be called before any event filter that may be on your application.
As the first approach does not require subclassing QApplication, it usually is the preferred one.The only reason to override QApplication::notify in your case would be if you needed to override it due to other reasons anyway, e.g. because you need to do anything related to your own custom events.
But looking at your requirements I would personally go for the following solution:
Install an event filter on qApp
Create a timer with a 30 seconds interval
Connect the timer to the lock screen method
Have your event filter reset the timer every time a mouse press is detected.
Dependent on your application you might also want to look for KeyPress events and maybe MouseMove events as well.

Qt events and signal/slots

In the Qt world, what is the difference of events and signal/slots?
Does one replace the other? Are events an abstraction of signal/slots?
In Qt, signals and events are both implementations of the Observer pattern. They are used in different situations because they have different strengths and weaknesses.
First of all let's define what we mean by 'Qt event' exactly: a virtual function in a Qt class, which you're expected to reimplement in a base class of yours if you want to handle the event. It's related to the Template Method pattern.
Note how I used the word "handle". Indeed, here's a basic difference between the intent of signals and events:
You "handle" events
You "get notified of" signal emissions
The difference is that when you "handle" the event, you take on the responsibility to "respond" with a behavior that is useful outside the class. For example, consider an app that has a button with a number on it. The app needs to let the user focus the button and change the number by pressing the "up" and "down" keyboard keys. Otherwise the button should function like a normal QPushButton (it can be clicked, etc). In Qt this is done by creating your own little reusable "component" (subclass of QPushButton), which reimplements QWidget::keyPressEvent. Pseudocode:
class NumericButton extends QPushButton
private void addToNumber(int value):
// ...
reimplement base.keyPressEvent(QKeyEvent event):
if(event.key == up)
this.addToNumber(1)
else if(event.key == down)
this.addToNumber(-1)
else
base.keyPressEvent(event)
See? This code presents a new abstraction: a widget that acts like a button, but with some extra functionality. We added this functionality very conveniently:
Since we reimplemented a virtual, our implementation automatically became encapsulated in our class. If Qt's designers had made keyPressEvent a signal, we would need to decide whether to inherit QPushButton or just externally connect to the signal. But that would be stupid, since in Qt you're always expected to inherit when writing a widget with a custom behavior (for good reason - reusability/modularity). So by making keyPressEvent an event, they convey their intent that keyPressEvent is just a basic building block of functionality. If it were a signal, it'd look like a user-facing thing, when it's not intended to be.
Since the base-class-implementation of the function is available, we easily implement the Chain-of-responsibility pattern by handling our special cases (up&down keys) and leaving the rest to the base class. You can see this would be nearly impossible if keyPressEvent were a signal.
The design of Qt is well thought out - they made us fall into the pit of success by making it easy to do the right thing and hard to do the wrong thing (by making keyPressEvent an event).
On the other hand, consider the simplest usage of QPushButton - just instantiating it and getting notified when it's clicked:
button = new QPushButton(this)
connect(button, SIGNAL(clicked()), SLOT(sayHello())
This is clearly meant to be done by the user of the class:
if we had to subclass QPushButton every time we want some button to notify us of a click, that would require a lot of subclasses for no good reason! A widget that always shows a "Hello world" messagebox when clicked is useful only in a single case - so it's totally not reusable. Again, we have no choice but to do the right thing - by connecting to it externally.
we may want to connect several slots to clicked() - or connect several signals to sayHello(). With signals there is no fuss. With subclassing you would have to sit down and ponder some class diagrams until you decide on an appropriate design.
Note that one of the places QPushButton emits clicked() is in its mousePressEvent() implementation. That doesn't mean clicked() and mousePressEvent() are interchangable - just that they're related.
So signals and events have different purposes (but are related in that both let you "subscribe" to a notification of something happening).
I don’t like the answers so far. – Let me concentrate on this part of the question:
Are events an abstraction of signal/slots?
Short answer: no. The long answer raises a “better” question: How are signals and events related?
An idle main loop (Qt’s for example) is usually “stuck” in a select() call of the operating system. That call makes the application “sleep”, while it passes a bunch of sockets or files or whatever to the kernel asking for: if something changes on these, let the select() call return. – And the kernel, as the master of the world, knows when that happens.
The result of that select() call could be: new data on the socket connect to X11, a packet to a UDP port we listen on came in, etc. – That stuff is neither a Qt signal, nor a Qt event, and the Qt main loop decides itself if it turns the fresh data into the one, the other or ignores it.
Qt could call a method (or several) like keyPressEvent(), effectively turning it into a Qt event. Or Qt emits a signal, which in effect looks up all functions registered for that signal, and calls them one after the other.
One difference of those two concepts is visible here: a slot has no vote on whether other slots registered to that signal will get called or not. – Events are more like a chain, and the event handler decides if it interrupts that chain or not. Signals look like a star or tree in this respect.
An event can trigger or be entirely turned into a signal (just emit one, and don’t call “super()”). A signal can be turned into an event (call an event handler).
What abstracts what depends on the case: the clicked()-signal abstracts mouse events (a button goes down and up again without too much moving around). Keyboard events are abstractions from lower levels (things like 果 or é are several key strokes on my system).
Maybe the focusInEvent() is an example of the opposite: it could use (and thus abstract) the clicked() signal, but I don’t know if it actually does.
The Qt documentation probably explains it best:
In Qt, events are objects, derived
from the abstract QEvent class, that
represent things that have happened
either within an application or as a
result of outside activity that the
application needs to know about.
Events can be received and handled by
any instance of a QObject subclass,
but they are especially relevant to
widgets. This document describes how
events are delivered and handled in a
typical application.
So events and signal/slots are two parallel mechanisms accomplishing the same things. In general, an event will be generated by an outside entity (for example, keyboard or mouse wheel) and will be delivered through the event loop in QApplication. In general, unless you set up the code, you will not be generating events. You might filter them through QObject::installEventFilter() or handle events in subclassed object by overriding the appropriate functions.
Signals and Slots are much easier to generate and receive and you can connect any two QObject subclasses. They are handled through the Metaclass (have a look at your moc_classname.cpp file for more), but most of the interclass communication that you will produce will probably use signals and slots. Signals can get delivered immediately or deferred via a queue (if you are using threads).
A signal can be generated.
Events are dispatched by the event loop. Each GUI program needs an event loop, whatever you write it Windows or Linux, using Qt, Win32 or any other GUI library. As well each thread has its own event loop. In Qt "GUI Event Loop" (which is the main loop of all Qt applications) is hidden, but you start it calling:
QApplication a(argc, argv);
return a.exec();
Messages OS and other applications send to your program are dispatched as events.
Signals and slots are Qt mechanisms. In the process of compilations using moc (meta-object compiler), they are changed to callback functions.
Event should have one receiver, which should dispatch it. No one else should get that event.
All slots connected to the emitted signal will be executed.
You shouldn't think of Signals as events, because as you can read in the Qt documentation:
When a signal is emitted, the slots connected to it are usually executed immediately, just like a normal function call. When this happens, the signals and
slots mechanism is totally independent
of any GUI event loop.
When you send an event, it must wait for some time until the event loop dispatches all events that came earlier. Because of this, execution of the code after sending event or signal is different. Code following sending an event will be run immediately. With the signals and slots mechanisms it depends on the connection type. Normally it will be executed after all slots. Using Qt::QueuedConnection, it will be executed immediately, just like events. Check all connection types in the Qt documentation.
There is an article that discusses event processing in some detail: http://www.packtpub.com/article/events-and-signals
It discussions the difference between events and signals here:
Events and signals are two parallel mechanisms used to accomplish the
same thing. As a general difference, signals are useful when using a
widget, whereas events are useful when implementing the widget. For
example, when we are using a widget like QPushButton, we are more
interested in its clicked() signal than in the low-level mouse press
or key press events that caused the signal to be emitted. But if we
are implementing the QPushButton class, we are more interested in the
implementation of code for mouse and key events. Also, we usually
handle events but get notified by signal emissions.
This seems to be a common way of talking about it, as the accepted answer uses some of the same phrases.
Note, please see helpful comments below on this answer from Kuba Ober, that make me wonder if it might be a bit simplistic.
TL;DR: Signals and slots are indirect method calls. Events are data structures. So they are quite different animals.
The only time when they come together is when slot calls are made across thread boundaries. The slot call arguments are packed up in a data structure and get sent as an event to the receiving thread's event queue. In the receiving thread, the QObject::event method unpacks the arguments, executes the call, and possibly returns the result if it was a blocking connection.
If we're willing to generalize to oblivion, one could think of events as as a way of invoking the target object's event method. This is an indirect method call, after a fashion - but I don't think it's a helpful way of thinking about it, even if it's a true statement.
'Event processing' by Leow Wee Kheng says:
Jasmine Blanchette says:
The main reason why you would use events rather than standard function calls, or signals and slots, is that events can be used both synchronously and asynchronously (depending on whether you call sendEvent() or postEvents()), whereas calling a function or invoking a slot is always synchronous. Another advantage of events is that they can be filtered.
Events (in a general sense of user/network interaction) are typically handled in Qt with signals/slots, but signals/slots can do plenty of other things.
QEvent and its subclasses are basically just little standardized data packages for the framework to communicate with your code. If you want to pay attention to the mouse in some way, you only have to look at the QMouseEvent API, and the library designers don't have to reinvent the wheel every time you need to figure out what the mouse did in some corner of the Qt API.
It is true that if you're waiting for events (again in the general case) of some sort, your slot will almost certainly accept a QEvent subclass as an argument.
With that said, signals and slots can certainly be used without QEvents, although you'll find that the original impetus for activating a signal will often be some kind of user interaction or other asynchronous activity. Sometimes, however, your code will just reach a point where firing off a certain signal will be the right thing to do. For example, firing off a signal connected to a progress bar during a long process doesn't involve a QEvent up to that point.
Another minor pragmatic consideration: emitting or receiving signals requires inheriting QObject whereas an object of any inheritance can post or send an event (since you invoke QCoreApplication.sendEvent() or postEvent()) This is usually not an issue but: to use signals PyQt strangely requires QObject to be the first super class, and you might not want to rearrange your inheritance order just to be able to send signals.)
In my opinion events are completely redundant and could be thrown out. There is no reason why signals could not be replaced by events or events by signals, except that Qt is already set up as it is. Queued signals are wrapped by events and events could conceivably be wrapped by signals, for example:
connect(this, &MyItem::mouseMove, [this](QMouseEvent*){});
Would replace the convenience mouseMoveEvent() function found in QWidget (but not in QQuickItem anymore) and would handle mouseMove signals that a scene manager would emit for the item. The fact that the signal is emitted on behalf of the item by some outside entity is unimportant and happens quite often in the world of Qt components, even though it is supposedly not allowed (Qt components often circumvent this rule). But Qt is a conglomerate of many different design decisions and pretty much cast in stone for fear of breaking old code (which happens often enough anyway).