2011-03-31 130 views
0

在我的數學應用程序中,我使用計時器來定期執行某些操作。這些操作也可以由我的用戶配置。現在,如果已經有另一個操作忙,我不希望這些操作被執行。防止計時器在某些事情已經很忙時運行(使用Qt)

E.g.如果用戶只是通過選擇一個菜單條目來開始一個複雜的計算,我不想執行我的定時器後面的操作。

問題是用戶可以通過許多不同的方式執行操作(通過菜單,通過點擊某處,通過彈出式菜單,通過拖放,...)。我實際上需要的是防止定時器在應用程序當前不在主事件循環中時關閉。

我會給出一個更具體的例子,以使其更清晰:

  • 在啓動時創建定時器
  • 如果計時器響起,我執行它,在實踐中,可以訪問幾乎所有的一些行動在應用程序的數據結構中。
  • 現在假設用戶啓動一個數學算法(通過菜單,通過點擊或拖動屏幕上的元素,他是如何開始的)。
    • 該算法將執行大量的計算(在主線程中)。由於它們在主線程中執行,所以定時器事件不會關閉。
    • 現在算法顯示一個消息框(可能是警告或問題)。
    • 當消息框打開時,事件再次被處理,包括我的計時器事件,這可能會執行不正確的計算,因爲已經有另一個算法在運行。

返工我的應用程序,使我謹邏輯到一個單獨的工作線程,或增加檢查我所有的行動是不可能在這一刻。所以請不要建議完全重寫我的應用程序。

我試過到目前爲止是這樣的:

  • 使用事件後發送事件,希望這一事件只會在主事件循環中執行。不幸的是,消息框的事件循環似乎也處理髮布的事件。
  • 使用QEvent :: WindowBlocked和QEvent :: WindowUnblocked事件來查看何時打開模態對話框。在我的計時器事件邏輯中,我可以檢查我們是否在QEvent :: WindowBlocked-QEvent :: WindowUnblocked調用之間。不幸的是,這些事件僅適用於由Qt本身創建的模態對話框,而不適用於其他對話框(例如Windows MessageBox或系統的打印機配置對話框)。此外,如果會有其他由子例程創建的事件循環,這個技巧也無濟於事。

我真正需要解決我的問題是一個簡單的函數,即:

  • 如果應用程序中的主要事件循環處理事件返回true
  • 如果應用程序正在處理事件在另一個[sub]事件循環中,它返回false

另一種方法是返回指示處理事件的「深度」的級別。

有人建議嗎?

+0

這可能正是您不想要的建議,但像這樣的情況似乎尖叫出您的數據的互斥保護。實質上,您有多個線程訪問相同的數據;所以使用互斥鎖來確保一次只有一個線程可以執行此操作。 – 2011-03-31 15:57:17

+0

這是單線程的。重新進入是由於創建新事件循環的例程中的阻塞調用。使用互斥鎖會導致系統死鎖。 – cgmb 2011-04-03 06:12:10

回答

0

您可以使用QAbstractEventDispatcher掛鉤到主線程/應用程序的事件循環中。 Conditionaly根據您的應用程序狀態過濾出QTimer事件。

+0

但是這需要我的應用程序中的每個動作都設置一個全局應用程序狀態。 – Patrick 2011-03-31 13:54:53

+0

如果你不能明確地設置應用程序狀態,你可能會以某種方式推斷它。在我看來,這種應用程序狀態的定義是不可避免的:您的應用程序已準備好處理用戶命令,或者它不是。 – Volker 2011-03-31 14:28:26

相關問題