Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to monitor QT signals?

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)

like image 350
Ronen Avatar asked Oct 01 '15 07:10

Ronen


3 Answers

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:

  1. 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.
  2. 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.

like image 163
Kuba hasn't forgotten Monica Avatar answered Sep 19 '22 22:09

Kuba hasn't forgotten Monica


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.

like image 21
MatrixAndrew Avatar answered Sep 18 '22 22:09

MatrixAndrew


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.

like image 40
TheDarkKnight Avatar answered Sep 18 '22 22:09

TheDarkKnight