I'm dealing with an application where many signals get fired after which a reconnect follows. I'll explain in detail how the application works, and also where my confusion starts.
1. Reconnecting a signal
In my application, I reconnect signals frequently. I will use the following static function for that, taken from the answer of @ekhumoro (and slightly modified) from this post: PyQt Widget connect() and disconnect()
def reconnect(signal, newhandler):
while True:
try:
signal.disconnect()
except TypeError:
break
if newhandler is not None:
signal.connect(newhandler)
2. The application
Imagine the function emitterFunc(self)
looping through a list of objects. Upon each iteration, the function connects mySignal
to an object, fires the signal and then disconnects mySignal
again at the start of the next iteration step. The fired signal also carries some payload, for example an object Foo()
.
EDIT:
The design shown above is simplified a lot. In the final design, the signal emitter and the receiving slot might operate in different threads.
For reasons that would lead us too far astray, I cannot just connect all the objects at once, emit a signal, and finally disconnect them all. I have to cycle through them one-by-one, doing a connect-emit-disconnect procedure.
Again for reasons that would lead us too far, I cannot just call these slots directly.
3. A mental image of the Signal-Slot mechanism
Over time, I have built up a mental image of how the Signal-Slot mechanism works. I imagine a Signal-Slot engine absorbing all fired signals and putting them in a Queue. Each signal awaits its turn. When time is ready, the engine passes the given signal to the appropriate handler. To do that correctly, the engine has some 'bookkeeping' work to ensure each signal ends up in the right slot.
4. Behavior of the Signal-Slot engine
Imagine we're at the nth iteration step. We connect self.mySignal
to object_n. Then we fire the signal with its payload. Almost immediately after doing that, we break the connection and establish a new connection to object_n+1. At the moment we break the connection, the fired signal probably didn't do its job yet. I can imagine three possible behaviors of the Signal-Slot engine:
[OPTION 1] The engine notices that the connection is broken, and discards
sig_n
from its Queue.[OPTION 2] The engine notices that the connection is re-established to another handler, and sends
sig_n
to the handler of object_n+1 (as soon as it gets to the front of the Queue).[OPTION 3] The engine doesn't change anything for
sig_n
. When fired, it was intended for the handler of object_n, and that's where it will end up.
5. My questions
My first question is pretty obvious by now. What is the correct Signal-Slot engine behavior? I hope it is the third option.
As a second question, I'd like to know to what extent the given mental image is correct. For example, can I rely on the signals getting out of the Queue in order? This question is less important - it's certainly not vital to my application.
The third question has to do with time efficiency. Is reconnecting to another handler time-consuming? Once I know the answer to the first question, I will proceed building the application and I could measure the reconnection time myself. So this question is not so vital. But if you know the answer anyway, please share :-)