wxPython:线程 GUI -->使用自定义事件处理程序
我正在尝试学习如何在主 GUI 应用程序上运行线程来执行串行端口发送/接收,同时保持 GUI 处于活动状态。我最好的谷歌搜索尝试让我找到了 wxpython wiki: http://wiki.wxpython.org/LongRunningTasks 其中提供了几个示例。我决定学习第一个示例,涉及在选择特定按钮时启动工作线程。
我无法理解自定义事件定义:
def EVT_RESULT(win, func):
"""Define Result Event."""
win.Connect(-1, -1, EVT_RESULT_ID, func)
class ResultEvent(wx.PyEvent):
"""Simple event to carry arbitrary result data."""
def __init__(self, data):
"""Init Result Event."""
wx.PyEvent.__init__(self)
self.SetEventType(EVT_RESULT_ID)
self.data = data
主要是
def EVT_RESULT(win, func):
"""Define Result Event."""
win.Connect(-1, -1, EVT_RESULT_ID, func)
我认为 EVT_RESULT 被放置在类之外,以便使其可以被两个类调用(使其成为全局的?)
并且..主 GUI 应用程序监视线程的进度via:
# Set up event handler for any worker thread results
EVT_RESULT(self,self.OnResult)
我还注意到,在很多例子中,当作者使用时,
from wx import *
他们只是将事物绑定在一起
EVT_SOME_NEW_EVENT(self, self.handler)
,而不是
wx.Bind(EVT_SOME_NEW_EVENT, self.handler)
“这并不能帮助我更快地理解它”。 谢谢,
I am trying to learn how to run a thread off the main GUI app to do my serial port sending/receiving while keeping my GUI alive. My best Googling attempts have landed me at the wxpython wiki on: http://wiki.wxpython.org/LongRunningTasks which provides several examples. I have settled on learning the first example, involving starting a worker thread when the particular button is selected.
I am having trouble understanding the custom-event-definition:
def EVT_RESULT(win, func):
"""Define Result Event."""
win.Connect(-1, -1, EVT_RESULT_ID, func)
class ResultEvent(wx.PyEvent):
"""Simple event to carry arbitrary result data."""
def __init__(self, data):
"""Init Result Event."""
wx.PyEvent.__init__(self)
self.SetEventType(EVT_RESULT_ID)
self.data = data
Primarily the
def EVT_RESULT(win, func):
"""Define Result Event."""
win.Connect(-1, -1, EVT_RESULT_ID, func)
I think EVT_RESULT is placed outside the classes so as to make it call-able by both classes (making it global?)
And.. the main GUI app monitors the thread's progress via:
# Set up event handler for any worker thread results
EVT_RESULT(self,self.OnResult)
I also notice that in a lot of examples, when the writer uses
from wx import *
they simply bind things by
EVT_SOME_NEW_EVENT(self, self.handler)
as opposed to
wx.Bind(EVT_SOME_NEW_EVENT, self.handler)
Which doesn't help me understand it any faster.
Thanks,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是定义自定义事件的旧风格。有关详细信息,请参阅迁移指南。
摘自迁移指南:
这是另一篇文章 我用几个示例程序制作的这些程序正是您所寻找的。
That's the old style of defining custom events. See the migration guide for more information.
Taken from the migration guide:
Here is another post that I made with a couple of example programs that do exactly what you are looking for.
你可以这样定义事件:
你可以这样发布事件:
像这样绑定它:
但是如果你只需要从主线程中的非主线程进行调用,你可以使用
wx.CallAfter
,这里是一个示例。当您不想对谁负责什么进行硬编码时,自定义事件非常有用(请参阅观察者设计模式)。例如,假设您有一个主窗口和几个子窗口。假设当主窗口发生某种变化时,需要刷新某些子窗口。在这种情况下,主窗口可以直接刷新这些子窗口,但更优雅的方法是定义一个自定义事件并让主窗口将其发布到自身(而不打扰谁需要对其做出反应)。然后,需要对该事件做出反应的子级可以通过绑定到该事件来自行完成(如果有多个事件,那么他们调用
event.Skip()
非常重要,以便所有绑定方法被调用)。You can define events like this:
You post the event like this:
Bind it like this:
But if you just need to make a call from a non-main thread in the main thread you can use
wx.CallAfter
, here is an example.Custom events are useful when you don't want to hard code who is responsible for what (see the observer design pattern). For example, lets say you have a main window and a couple of child windows. Suppose that some of the child windows need to be refreshed when a certain change occurs in the main window. The main window could directly refresh those child windows in such a case but a more elegant approach would be to define a custom event and have the main window post it to itself (and not bother who needs to react to it). Then the children that need to react to that event can do it them selves by binding to it (and if there is more than one it is important that they call
event.Skip()
so that all of the bound methods get called).您可能想要使用 Python 线程和队列,而不是自定义事件。我有一个 wxPython 程序(OpenSTV),它加载大文件,导致 gui 在加载过程中冻结。为了防止冻结,我调度一个线程来加载文件并使用队列在 GUI 和线程之间进行通信(例如,向 GUI 传达异常)。
You may want to use Python threads and queues and not custom events. I have a wxPython program (OpenSTV) that loads large files that caused the gui to freeze during the loading. To prevent the freezing, I dispatch a thread to load the file and use a queue to communicate between the gui and the thread (e.g., to communicate an exception to the GUI).