Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem with Qt::QueuedConnection, signal delivered after disconnect

Tags:

qt

I just discovered interesting behavior of queued connection in Qt 4.6:

First queued connection is made:

connect(someSender, SIGNAL(completed()), this, SLOT(handleCompletion()), Qt::QueuedConnection)

Then someSender sends the signal:

emit completed()

Before receiving signal (as it is in queue), I disconnect from the signal:

disconnect(someSender, SIGNAL(completed()), this, SLOT(handleCompletion())

Still, handleCompletion slot is invoked at next eventloop iteration. I can prevent this from happening by using someSender->blockSignals(true) at correct point, but it feels awful not to mention having some boolean flag to disable slot's functionality.

Especially, I feel amazed that this behavior is not mentioned in Qt documentation (at least I haven't found).

Finally the question: any sensible way to avoid this from happening?

like image 989
user110418 Avatar asked Mar 28 '10 08:03

user110418


1 Answers

I think Qt is behaving in the most intuitive way.

When you do emit completed(), it makes sense for the signal to immediately activate or queue all connected slots. If queued slots could be unqueued as a result of a disconnect, it would be more difficult to understand, and more prone to race conditions. Also, consider more complex scenarios: e.g. so if disconnecting removes it from the queue, does reconnecting put it back?

If it worked the way you'd expected, then in place of this question there'd be "Problem with Qt::QueuedConnection, signal not delivered after disconnect".

As for the sensible way to avoid this: you should redesign your code so that neither the sender nor receiver have to care if the signal is connected directly or queued. I'd recommend that neither the sender nor receiver calls QObject::connect and this is done by a third class. It's not clear if this will entirely solve your problem, it depends on where and why you're doing the disconnect.

like image 150
rohanpm Avatar answered Oct 01 '22 22:10

rohanpm