Problem with Qt :: QueuedConnection, signal delivered after disconnection

I just discovered an interesting queue behavior in Qt 4.6:

The first connection in the queue is completed:

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

Then someSender sends a signal:

 emit completed() 

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

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

However, the handleCompletion slot is called on the next iteration of the eventloop. I can prevent this by using someSender-> blockSignals (true) at the right point, but it feels awful, not to mention the presence of some logical flag to disable the functionality of the slot.

In particular, I am surprised that this behavior is not mentioned in the Qt documentation (at least I have not found).

Finally, the question is: is there any reasonable way to avoid this?

+4
source share
1 answer

I think Qt behaves in the most intuitive way.

When you execute emit completed() , it makes sense to immediately activate or queue all connected slots. If the queues in the queue could be freed due to disconnection, it would be more difficult to understand and more prone to race conditions. Also, consider more complex scenarios: for example. so if disconnecting removes it from the queue, reconnects it back?

If this worked as you expected, then instead of this question there would be "a problem with Qt :: QueuedConnection, the signal was not delivered after the shutdown."

As for a reasonable way to avoid this: you must reconfigure your code so that neither the sender nor the receiver cares whether the signal is directly connected or queued. I would recommend that neither the sender nor the recipient call QObject::connect , and this is done by the third class. It is not clear whether this will completely solve your problem, it depends on where and why you are disconnect .

+7
source

Source: https://habr.com/ru/post/1305345/


All Articles