Qt主事件队列被阻止时的QTimer超时处理

时间:2015-06-25 16:52:10

标签: qt events timer

如果我以固定间隔启动QTimer,但是对超时信号作出反应的插槽会阻塞主循环的时间超过另一个定时器间隔,会发生什么情况。然后,一旦事件循环再次运行,那么timout信号是否会堆叠在Qt主事件循环上并一个接一个地处理?

如果是,如果事件队列中堆叠了多个超时事件但是在处理它们之前停用了计时器会发生什么?

1 个答案:

答案 0 :(得分:4)

If QTimer object and the signal receiver belong to one thread, no queuing happens. timeout() signal will not (and cannot) be sent again until control flow goes to the event loop, and that won't happen until the slot is completely executed (unless QApplication::processEvents is called in the slot, which can turn this into a mess). But if your slot was being executed longer than the timer's interval, timeout() will be sent once the event loop is free, so your slot will be immedately called again. But QTimer will not send two timeout() signals closer than its interval. If QTimer is in another thread, and that thread is not busy with something else, it will send timeout() signals regularly regardless of how well slot in another thread goes. This is where Qt's signal-slot system comes in. And it will queue emitted signals. If your slot is slow, it will call it multiple times without delay. If you stop the timer, it won't undo already sent signals and the slot may be called multiple times after it. Additionally, if you stop the timer, there is always a possibility that another signal is being sent just in this moment and your slot will be called once again. If you want strict intervals between slot invocations regardless of the slot's executing time, you should use single-shot timers. At the end of your slot, start a single-shot timer. When it's timed out, it will invoke your slot and deactivate, so you can start it again at the end of the slot. If your program's logic depends on the timer's state, you should check that the timer is active at the start of your slot. It's not guaranteed that the timer is active when the slot is being executed.