1. 重新连接信号
在我的应用程序中,我经常重新连接信号。我将使用以下静态函数进行操作,该函数取自@ekhumoro的答案(稍作修改)从此帖子中获取: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. 应用程序
想象一下函数emitterFunc(self)
在循环遍历对象列表。在每次迭代中,该函数将mySignal
连接到一个对象,触发信号,然后在下一次迭代步骤开始时再次断开mySignal
的连接。触发的信号还携带一些有效负载,例如一个对象Foo()
。
编辑:
上面显示的设计已经大大简化了。在最终设计中,信号发射器和接收插槽可能在不同的线程中运行。
由于种种原因,我不能一次性连接所有对象,然后发射信号,最后断开它们所有的连接。我必须逐个地循环它们,执行连接-发射-断开的过程。
同样出于一些原因,我不能直接调用这些插槽。
3. Signal-Slot机制的心理形象
随着时间的推移,我已经建立了一个关于Signal-Slot机制如何工作的心理形象。我想象一个Signal-Slot引擎吸收所有触发的信号并将它们放在队列中。每个信号都等待着自己的时机。当时机成熟时,引擎将给定的信号传递给相应的处理程序。为了正确地做到这一点,引擎需要一些“簿记”工作,以确保每个信号都最终到达正确的插槽。
4. Signal-Slot引擎的行为
假设我们在第n次迭代步骤中。我们将self.mySignal
连接到object_n。然后我们使用有效负载触发信号。几乎在这样做之后,我们就会断开连接,并建立一个新的连接到object_n+1。在断开连接的那一刻,触发的信号可能还没有完成它的工作。我可以想象Signal-Slot引擎有三种可能的行为:
[选项1] 引擎注意到连接已中断,从其队列中丢弃
sig_n
。[选项2] 引擎注意到已重新连接到另一个处理程序,并在
sig_n
到达队列前端时将其发送到 object_n+1 的处理程序。[选项3] 引擎不会为
sig_n
更改任何内容。触发时,它是用于 object_n 处理程序的,也将在那里结束。
5. 我的问题
我的第一个问题现在已经非常明显了。正确的信号-槽引擎行为是什么?我希望它是第三个选项。
作为第二个问题,我想知道给定的心理图像在多大程度上是正确的。例如,我可以依赖信号按顺序从队列中出来吗?这个问题不太重要——对于我的应用程序来说肯定不是至关重要的。
第三个问题与时间效率有关。重新连接到另一个处理程序是否耗时?一旦我知道了第一个问题的答案,我将继续构建应用程序,我可以自己测量重新连接的时间。因此,这个问题并不是非常重要。但如果您知道答案,请分享 :-)
QMetaCallEvent
和直接调用。第三种是什么?---(2)您说事情出错的可能性非常小,所以您将我的[OPTION 3]
标记为正确。当您说“可能性非常小”时,我有点不愿意依赖它。你怎么看? - K.MulierQMetaCallEvent
事件。 (2)几乎没有机会防止在发出信号后调用插槽,并且使用disconnect
根本无法做到这一点。 - p-a-o-l-o