每 wx.App.MainLoop 次执行执行一次方法,无需重复 wx.CallAfter 次调用
Executing method once per wx.App.MainLoop execution without repeat wx.CallAfter calls
我正在使用 wxpython 创建一个使用 MVC 设计模式的 GUI。我正在使用带有控制器的状态机来跟踪应用程序的状态,并且希望在每次 wx.App.MainLoop()
函数运行时只执行一次状态转换方法。我希望它在 MainLoop()
函数期间在一致的位置执行,所以我宁愿避免线程或 wx.CallLater()
.
有没有办法使用 wx.CallAfter()
或类似方法永久添加方法,以便每次通过 MainLoop()
执行一次?
我曾尝试查看 wx.App.GetMainLoop()
的 return 对象,但没有找到如何使用该对象实现上述功能的方法。
也许你认为它比实际情况更复杂。在空闲时间强制轮询 GUI 会导致处理器负载过高。假设您的程序包含一个 GUI、状态机和一些不是来自 GUI 的输入(例如来自网络)。大概你的状态机会在三种情况下改变状态:
- 用户在 GUI 中输入内容
- 内部状态改变
- 外部 I/O(不通过 GUI)正在发生
对于这些情况,您will/can执行以下操作:
GUI 输入是事件驱动的:您决定将哪些用户输入视为状态改变。这可以从单击 OK
按钮到捕获 EVT_TEXT
或鼠标事件。此处无需投票
内部状态变化:
- 状态机事件循环中的状态变化(如果有的话)。如果状态机中有事件循环,则需要在单独的线程中将其关闭,否则 GUI 会阻塞。您必须以线程安全的方式将状态机中的更改反馈给 GUI(最简单的方法是
wx.CallAfter
)。参见 the very helpful wxPython wiki。
- 每隔一段时间(例如,每 100 毫秒)使用
wx.Timer
调用状态机。在这种情况下,状态机甚至不需要自己的线程和线程安全通信。
原则上,与第 2 点相同的事情可以为 I/O 完成。分拆线程或使用计时器定期调用 I/O-machinery.
您还可以绑定到 EVT_IDLE
,每当事件循环中没有更多事件挂起时,它就会被调用。但是当然这只会导致不必要的轮询。
我正在使用 wxpython 创建一个使用 MVC 设计模式的 GUI。我正在使用带有控制器的状态机来跟踪应用程序的状态,并且希望在每次 wx.App.MainLoop()
函数运行时只执行一次状态转换方法。我希望它在 MainLoop()
函数期间在一致的位置执行,所以我宁愿避免线程或 wx.CallLater()
.
有没有办法使用 wx.CallAfter()
或类似方法永久添加方法,以便每次通过 MainLoop()
执行一次?
我曾尝试查看 wx.App.GetMainLoop()
的 return 对象,但没有找到如何使用该对象实现上述功能的方法。
也许你认为它比实际情况更复杂。在空闲时间强制轮询 GUI 会导致处理器负载过高。假设您的程序包含一个 GUI、状态机和一些不是来自 GUI 的输入(例如来自网络)。大概你的状态机会在三种情况下改变状态:
- 用户在 GUI 中输入内容
- 内部状态改变
- 外部 I/O(不通过 GUI)正在发生
对于这些情况,您will/can执行以下操作:
GUI 输入是事件驱动的:您决定将哪些用户输入视为状态改变。这可以从单击
OK
按钮到捕获EVT_TEXT
或鼠标事件。此处无需投票内部状态变化:
- 状态机事件循环中的状态变化(如果有的话)。如果状态机中有事件循环,则需要在单独的线程中将其关闭,否则 GUI 会阻塞。您必须以线程安全的方式将状态机中的更改反馈给 GUI(最简单的方法是
wx.CallAfter
)。参见 the very helpful wxPython wiki。 - 每隔一段时间(例如,每 100 毫秒)使用
wx.Timer
调用状态机。在这种情况下,状态机甚至不需要自己的线程和线程安全通信。
- 状态机事件循环中的状态变化(如果有的话)。如果状态机中有事件循环,则需要在单独的线程中将其关闭,否则 GUI 会阻塞。您必须以线程安全的方式将状态机中的更改反馈给 GUI(最简单的方法是
原则上,与第 2 点相同的事情可以为 I/O 完成。分拆线程或使用计时器定期调用 I/O-machinery.
您还可以绑定到 EVT_IDLE
,每当事件循环中没有更多事件挂起时,它就会被调用。但是当然这只会导致不必要的轮询。