Qt :: QueuedConnection出现问题,断开连接后发出信号

时间:2010-03-28 08:50:55

标签: qt

我刚刚在Qt 4.6中发现了有趣的排队连接行为:

首先排队连接:

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

然后someSender发送信号:

emit completed()

在接收信号之前(因为它在队列中),我断开信号:

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

仍然,在下一个eventloop迭代时调用handleCompletion槽。我可以通过在正确的点使用someSender-> blockSignals(true)来防止这种情况发生,但是如果没有提到一些布尔标志来禁用插槽的功能,那就太糟糕了。

特别是,我感到惊讶的是Qt文档中没有提到这种行为(至少我没有找到)。

最后一个问题:是否有任何明智的方法可以避免这种情况发生?

1 个答案:

答案 0 :(得分:8)

我认为Qt的行为方式最直观。

执行emit completed()时,信号立即激活或排队所有连接的插槽是有意义的。如果排队的插槽可能因断开连接而排队,则更难以理解,并且更容易出现竞争条件。另外,考虑更复杂的情况:例如因此,如果断开连接将其从队列中删除,重新连接会将其重新放回吗?

如果它按照你预期的方式运行,那么代替这个问题就会出现“Qt :: QueuedConnection问题,断开连接后信号没有传递”。

至于避免这种情况的合理方法:您应该重新设计代码,以便发送方和接收方都不必关心信号是直接连接还是排队。我建议发送方和接收方都不要调用QObject::connect,这是由第三类完成的。目前尚不清楚这是否能完全解决您的问题,这取决于您在disconnect执行的地点和原因。