Qt主事件队列阻塞时QTimer超时处理
QTimer timeout processing when Qt main event queue is blocked
如果我启动一个定期触发的 QTimer,但对超时信号作出反应的插槽阻塞主循环的时间比另一个定时器间隔长,会发生什么情况。超时信号是否会被堆叠在Qt主事件循环中,并在事件循环再次运行时一个接一个地处理?
如果是,如果多个超时事件堆叠在事件队列中,但定时器在处理它们之前被停用,会发生什么情况?
如果QTimer
对象和信号接收器属于一个线程,则不会发生排队。在控制流进入事件循环之前,timeout()
信号不会(也不能)再次发送,并且在槽完全执行之前不会发生(除非在槽中调用 QApplication::processEvents
,这可以把它变成一团糟)。但是,如果您的插槽执行时间长于计时器的间隔,一旦事件循环空闲,将发送 timeout()
,因此您的插槽将立即再次调用。但是 QTimer
不会发送两个 timeout()
比其间隔更近的信号。
如果 QTimer
在另一个线程中,并且该线程不忙于其他事情,它将定期发送 timeout()
信号,而不管另一个线程中的槽运行得如何。这就是 Qt 的信号槽系统发挥作用的地方。它将对发出的信号进行排队。如果你的插槽很慢,它会毫不拖延地多次调用它。如果您停止计时器,它不会撤消已发送的信号,并且可能会在它之后多次调用该插槽。此外,如果您停止计时器,则总是有可能此时正在发送另一个信号,您的插槽将再次被调用。
如果无论插槽的执行时间如何,您都希望插槽调用之间有严格的间隔,您应该使用单次计时器。在您的插槽结束时,启动单次计时器。当它超时时,它将调用您的插槽并停用,因此您可以在插槽结束时再次启动它。
如果您的程序的逻辑取决于计时器的状态,您应该检查计时器在您的插槽开始时是否处于活动状态。不保证定时器在执行时槽时处于活动状态。
如果我启动一个定期触发的 QTimer,但对超时信号作出反应的插槽阻塞主循环的时间比另一个定时器间隔长,会发生什么情况。超时信号是否会被堆叠在Qt主事件循环中,并在事件循环再次运行时一个接一个地处理?
如果是,如果多个超时事件堆叠在事件队列中,但定时器在处理它们之前被停用,会发生什么情况?
如果QTimer
对象和信号接收器属于一个线程,则不会发生排队。在控制流进入事件循环之前,timeout()
信号不会(也不能)再次发送,并且在槽完全执行之前不会发生(除非在槽中调用 QApplication::processEvents
,这可以把它变成一团糟)。但是,如果您的插槽执行时间长于计时器的间隔,一旦事件循环空闲,将发送 timeout()
,因此您的插槽将立即再次调用。但是 QTimer
不会发送两个 timeout()
比其间隔更近的信号。
如果 QTimer
在另一个线程中,并且该线程不忙于其他事情,它将定期发送 timeout()
信号,而不管另一个线程中的槽运行得如何。这就是 Qt 的信号槽系统发挥作用的地方。它将对发出的信号进行排队。如果你的插槽很慢,它会毫不拖延地多次调用它。如果您停止计时器,它不会撤消已发送的信号,并且可能会在它之后多次调用该插槽。此外,如果您停止计时器,则总是有可能此时正在发送另一个信号,您的插槽将再次被调用。
如果无论插槽的执行时间如何,您都希望插槽调用之间有严格的间隔,您应该使用单次计时器。在您的插槽结束时,启动单次计时器。当它超时时,它将调用您的插槽并停用,因此您可以在插槽结束时再次启动它。
如果您的程序的逻辑取决于计时器的状态,您应该检查计时器在您的插槽开始时是否处于活动状态。不保证定时器在执行时槽时处于活动状态。