I've injected myself into a Qt application, and I'm attempting to figure out what signals a given slot is connected to, but can't find any information on doing this. Is there a mechanism for doing this out of the box? If so, is this exposed to QtScript? (If not, I can wrap it easily enough.)
If there is no such mechanism, what would be the best way to add it? I cannot manipulate the existing application outside of simple hooking, but I could hook QObject::connect and store the connections myself, just not sure if that's the best way to go about it.
Welcome to SO ! You can have as many signals you want connected to one slot and vice versa. If several slots are connected to one signal, the slots will be executed one after the other, in the order they have been connected, when the signal is emitted.
To connect the signal to the slot, we use QObject::connect(). There are several ways to connect signal and slots. The first is to use function pointers: connect(sender, &QObject::destroyed, this, &MyObject::objectDestroyed);
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.
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:
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.
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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With