Determine signals connected to a given slot in Qt

Solution 1:

I think Qt stores the slots a given signal is connected to, so that when you emit it all receivers are called, therefore you can access the list of receivers:

For debugging purposes, you have:

void QObject::dumpObjectInfo ()

Dumps information about signal connections, etc. for this object to the debug output.

This function is useful for debugging, but does nothing if the library has been compiled in release mode (i.e. without debugging information).

And the list of slots a signal is connected:

int QObject::receivers ( const char * signal ) const [protected]

Returns the number of receivers connected to the signal.

The metaObject() gives you the QMetaMethod for the slot, but it has no information about its connections.

However, if you know the objects, you can go over all the the signals (using the meta object, testing the method type for signal) and build a reverse index with the slots receivers() gives you.

Solution 2:

There is no way to safely iterate the list of signal-slot connections without holding Qt's internal mutexes/semaphores. The signals and slots can come and go at any time, so at best you'd get a list that is not guaranteed to be correct - and thus useless.

Whatever hooking you do in QObject::connect is by itself insufficient. The data you get from such hooks will suffer the following:

  1. You may have pointers to objects that are already deleted by the time you try to access them. You can mitigate this by using QPointer, but this only works for objects that live in the thread where you run your code. You'd need to inject your object into other threads to collect object lists there.

  2. You may have connections that don't exist anymore. Even hooking QObject::disconnect would be insufficient, since connections are deleted when objects cease to exist.

The problem you're facing is quite complex, and any robust solution would not be merely limited to "hooking" QObject::connect.

Alas, you haven't said why you need the list of signals that attach to a slot. What is the purpose of it?

Solution 3:

After digging around in the Qt code base and documentation (I got lots of helpful tips from here and elsewhere), I ended up settling on hooking QObject::connect (the static overload). Why? Well, the other solutions require you to know what objects are providing the signals, dig into private fields, or have to have a debug build of Qt. In the end, hooking QObject::connect gives you everything connected in the application, and you can trivially map back to the slots.