开发者

Preventing timers from running when something is already busy (using Qt)

In my mathematical application I am using timers to regularly perform certain actions. These actions can also be configured by my users. Now I don't want these actions to be executed if there is already another action busy.

E.g. if the user just started a complex calculation by selecting a menu entry, I don't want to execute the actions behind my timers.

Problem is that the user can execute an action via a lot of different ways (via the menu, by clicking somewhere, via popup menu, via drag-and-drop, ...). What I effectively want is to prevent the timers from going off if the application is currently not in the main event loop.

I will give a more concrete example to make it clearer:

  • At startup I create the timers
  • If a timer goes off, I execute some actions which, in practice, could access almost every bit in may application's data structure.
  • Now suppose the user starts a mathematical algorithm (via the menu, by clicking or by dragging elements on the screen, it doesn't matter how he started it).
    • The algorithm will perform lots of calculations (in the main thread). Since they are executed in the main thread, the timer events will not go off.
    • Now the algorithm shows a message box (could be a warning or a question).
    • While the message box is open, events are processed again, including my timer events, which could possibly perform incorrect calculations because there is already another algorithm running.

Reworking my application so that I m开发者_JAVA技巧ove logic to a separate worker thread, or adding checks to all of my actions isn't possible at this moment. So please don't suggest to completely rework my application.

What I tried so far is the following:

  • Using postEvent to send an event, hoping that this event would only be executed in the main event loop. Unfortunately, also the message box's event loop seems to process posted events.
  • Using the QEvent::WindowBlocked and QEvent::WindowUnblocked events to see when a modal dialog was opened. In my timer-event-logic I can check whether we are between QEvent::WindowBlocked-QEvent::WindowUnblocked calls or not. Unfortunately, these events only work for modal dialogs created by Qt itself, not for other dialogs (e.g. the Windows MessageBox, or the system's printer configuration dialog). Also, this trick would not help if there would be other event loops created by sub routines.

What I actually need to solve my problem is a simple function, that:

  • If the application is handling an event in the main event loop returns true
  • If the application is handling an event in another [sub] event loop, it returns false

An alternative could be to return a level that indicates the 'depth' of the handled event.

Anyone suggestions?


You could hook into the event loop of your main thread/application using QAbstractEventDispatcher. Conditionaly filter out QTimer-events based on your application state.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜