每次执行wx.App.MainLoop执行一次方法,而不重复wx.CallAfter调用

时间:2015-01-15 05:58:57

标签: python events wxpython

我使用wxpython使用MVC设计模式创建GUI。我正在使用带控制器的状态机来跟踪应用程序的状态,并希望每次wx.App.MainLoop()函数运行时都执行一次状态转换方法。我想在MainLoop()函数期间在一致的位置执行此操作,因此我宁愿避免使用线程或wx.CallLater()

有没有办法使用wx.CallAfter()或类似方法永久添加方法,以便每次只通过MainLoop()执行一次?

我已经尝试查看wx.App.GetMainLoop()的返回对象,但没有找到如何使用该对象实现上述功能。

1 个答案:

答案 0 :(得分:0)

Mabye你认为它比它更复杂。在空闲时间内对GUI进行强力轮询是高处理器负载的一个因素。据推测,您的程序包含GUI,状态机和一些不是来自GUI的输入(例如来自网络)。据推测,你的状态机会三次改变状态:

  1. 用户在GUI中输入内容
  2. 内部状态发生变化
  3. 外部I / O(不在GUI上)正在发生
  4. 对于这些情况,您将/可以执行以下操作:

    1. GUI输入是事件驱动的:您决定将用户输入视为状态更改。这可以是点击OK按钮到捕获EVT_TEXT或鼠标事件。无需在此进行投票。

    2. 内部状态变化:

      • 状态机事件循环中的状态更改(如果有)。如果状态机中存在事件循环,则需要在单独的线程中将其旋转,否则GUI将阻塞。您必须以线程安全的方式将状态机中的更改传回GUI(最简单的方法是wx.CallAfter)。见the very helpful wxPython wiki
      • 使用wx.Timer每隔一段时间(例如每100毫秒)调用状态机。在这种情况下,状态机甚至不需要自己的线程和线程安全通信。
    3. 原则上,对于I / O,可以执行与第2点相同的操作。剥离线程或使用计时器来定期调用I / O机器。

    4. 您还可以绑定到EVT_IDLE,每次事件循环中没有更多事件待处理时,将调用{{1}}。但当然这只会导致不必要的民意调查。