【发布时间】:2011-03-31 10:19:33
【问题描述】:
在我的数学应用程序中,我使用计时器来定期执行某些操作。这些操作也可以由我的用户配置。现在,如果已经有另一个动作忙,我不希望执行这些动作。
例如如果用户刚刚通过选择菜单项开始了复杂的计算,我不想执行我的计时器后面的操作。
问题是用户可以通过许多不同的方式执行操作(通过菜单、通过单击某处、通过弹出菜单、通过拖放,...)。如果应用程序当前不在主事件循环中,我实际上想要的是防止计时器关闭。
我会举一个更具体的例子来说明清楚:
- 在启动时我会创建计时器
- 如果计时器关闭,我会执行一些操作,这些操作实际上可以访问应用程序数据结构中的几乎所有位。
- 现在假设用户启动了一个数学算法(通过菜单、单击或拖动屏幕上的元素,不管他是如何启动它的)。
- 算法将执行大量计算(在主线程中)。由于它们在主线程中执行,因此计时器事件不会发生。
- 现在算法会显示一个消息框(可能是警告或问题)。
- 当消息框打开时,会再次处理事件,包括我的计时器事件,这可能会执行不正确的计算,因为已经有另一个算法在运行。
目前无法重新设计我的应用程序,以便将逻辑移至单独的工作线程,或者对我的所有操作添加检查。所以请不要建议完全修改我的应用程序。
到目前为止,我尝试了以下内容:
- 使用postEvent发送事件,希望这个事件只在主事件循环中执行。不幸的是,消息框的事件循环似乎也在处理已发布的事件。
- 使用 QEvent::WindowBlocked 和 QEvent::WindowUnblocked 事件查看模式对话框何时打开。在我的计时器事件逻辑中,我可以检查我们是否在 QEvent::WindowBlocked-QEvent::WindowUnblocked 调用之间。不幸的是,这些事件仅适用于 Qt 本身创建的模式对话框,不适用于其他对话框(例如 Windows 消息框或系统的打印机配置对话框)。此外,如果子例程会创建其他事件循环,此技巧也无济于事。
我真正需要解决我的问题是一个简单的功能,即:
- 如果应用程序正在处理主事件循环中的事件,则返回 true
- 如果应用程序正在另一个 [sub] 事件循环中处理事件,则返回 false
另一种方法是返回一个级别,指示所处理事件的“深度”。
有人建议吗?
【问题讨论】:
-
这可能正是您不想要的建议,但这种情况似乎需要对您的数据进行互斥保护。本质上,您有多个线程访问相同的数据;所以使用互斥锁来确保一次只有一个线程可以执行此操作。
-
这是单线程的。重新进入是由于创建新事件循环的例程中的阻塞调用。使用互斥锁会导致系统死锁。