2015-06-25 80 views
2

如果我以固定間隔啓動QTimer觸發,但對超時信號作出反應的插槽阻塞主循環的時間長於另一個定時器時間間隔,會發生什麼情況。那麼,當事件循環再次運行時,timout信號會被疊加到Qt主事件循環中並且一個接一個地處理嗎?當Qt主事件隊列被阻塞時QTimer超時處理

如果是,如果事件隊列中堆疊了多個超時事件但定時器在被處理之前被停用,會發生什麼?

回答

2

如果QTimer對象和信號接收器屬於一個線程,則不會發生排隊。 timeout()信號在控制流程進入事件循環之前不會(也不能)再次發送,並且直到插槽完全執行(除非在插槽中調用QApplication::processEvents,否則會導致混亂),這種情況不會發生。但是如果您的插槽執行的時間超過了定時器的時間間隔,那麼一旦事件循環空閒,將會發送timeout(),因此您的插槽將被立即再次調用。但QTimer將不會發送兩個timeout()信號比它的間隔更近。

如果QTimer在另一個線程中,並且該線程沒有忙於其他線程,它將定期發送timeout()信號,而不管另一個線程中的插槽性能如何。這是Qt的信號時隙系統進入的地方,它會排隊發射的信號。如果您的插槽速度很慢,它會立即多次調用它。如果您停止定時器,它將不會撤消已發送的信號,並且可能在其後多次調用該插槽。此外,如果您停止計時器,則此時將始終有可能發送另一個信號,並且您的插槽將再次被調用。

如果您希望槽位調用之間的時間間隔嚴格(無論槽位的執行時間是多少),則應使用單次定時器。在您的插槽結束時,啓動一次性計時器。超時後,它將調用您的插槽並取消激活,以便您可以在插槽末尾再次啓動它。

如果您的程序邏輯取決於計時器的狀態,您應該檢查計時器在插槽開始時是否處於活動狀態。無法保證在插槽執行時定時器處於活動狀態。