wxPython——做自定义事件的更简单的方法?

wxPython -- easier way to do custom events?

在我的项目中,我使用 wxPython 并且有许多必须捕获的自定义事件,通常是在变量更改时。所以,我是这样设置的:

- Event happens (inside a function), it sends a louie signal
- Event Handler catches all event louie signals and performs a func call
- Function call posts the event
- Binding from widget catches it
- Widget sends it to a function in the Event Handler for handling

这似乎是一个非常多的迂回。难道不应该有一种方法可以简单地捕获绑定中的变量更改并将其发送给函数吗?我的感觉告诉我,我的做法全错了。有没有更简单的方法?

编辑 1:这是我设置的最小可运行代码,louie 调度是因为线程:

import time
import threading
import wx
from wx.lib.newevent import NewEvent
from louie import dispatcher

customEvent, EVT_CUSTOM_TEST = NewEvent()

def eventFire(changeTo):
    global customEvent
    changerContainer = customEvent(changeTo=changeTo)
    wx.PostEvent(text, changerContainer)

def change(event):
    text.SetLabel(event.changeTo)

class customThread(threading.Thread):

    def __init__(self, group=None, target=None, name=None, verbose=None, **kwargs):
        super(customThread, self).__init__(group=group, target=target, name=name, verbose=verbose)
        self.daemon = True

    def run(self):
        for i in range(10):
            if i == 5:
                dispatcher.send("CHANGE ME", changeTo="Changed Text")
            time.sleep(1)

dispatcher.connect(eventFire, "CHANGE ME")

app = wx.App()
frame = wx.Frame(None, wx.ID_ANY, title="test", size=(100,100))
panel = wx.Panel(frame)
text = wx.StaticText(panel, wx.ID_ANY, "Tester")
frame.Center()
frame.Show()
text.Bind(EVT_CUSTOM_TEST, change)
newThread = customThread()
newThread.start()
app.MainLoop()

编辑 2:使用 wxPython 2.8.12.1 和 Ubuntu 14.04

您可以在wxPython 中使用线程并且只调用一个线程安全的方法而不是使用调度程序。线程安全的方法是 wx.PostEventwx.CallAfter。我喜欢使用 pubsub 来传递数据。所以而不是

dispatcher.send("CHANGE ME", changeTo="Changed Text")

我会做类似的事情

wx.CallAfter(Publisher().sendMessage, "msg_name", "Changed Text")

然后将触发 pubsub 连接到的方法。所以可以做一个通用的方法

def change(text):
    text.SetLabel(text)

并通过 pubsub 调用它。以下是一些链接:

请注意,该文章使用 wxPython 2.8 并且 pubsub API 在 2.9+ 中发生了变化。所以你可能也想看看这个: