python - wx.lib.pubsub.Publisher在按钮点击时无法工作?
我正在用 MVC 模式开发一个应用程序,使用的是 wxPython,但遇到了一个关于 wx.lib.pubsub.Publisher 的问题。
我希望我的控制器和视图尽量分开。比如说,我不想让控制器知道视图中按钮的名字。在 wxPython 的示例 中,控制器必须知道这些名字,这样才能把动作绑定到这些按钮上。
class Controller:
...
self.view2.add.Bind(wx.EVT_BUTTON, self.AddMoney)
self.view2.remove.Bind(wx.EVT_BUTTON, self.RemoveMoney)
我想过要“解耦”一下,改用 wx.lib.pubsub.Publisher
的消息来处理:
from wx.lib.pubsub import Publisher as pub
class Controller:
...
pub.subscribe(self.AddMoney, "MONEY ADDED")
pub.subscribe(self.RemoveMoney, "MONEY REMOVED")
视图会把控件绑定到一个动作,这个动作只是发送消息。
但是,结果似乎不太对。要么视图不发送事件,要么控制器不接收来自视图的消息。我也不太确定。
这里有一个小示例应用,展示了我的问题(我在 python 2.6.6 和 wxPython 2.8 上测试过)。
import wxversion
wxversion.ensureMinimal('2.8')
import wx
from wx.lib.pubsub import Publisher as pub
class View(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="Main View")
self.button = wx.Button(self, -1, "foo?")
self.button.Bind(wx.EVT_BUTTON, self.ChangeFoo)
def ChangeFoo(self, evt):
print('Binding works')
pub.sendMessage("FOO CHANGED")
class Controller:
def __init__(self, app):
self.view = View()
pub.subscribe(self.FooChanged, "FOO CHANGED")
self.view.Show()
def FooChanged(self, message):
print('Messaging works')
app = wx.App(False)
Controller(app)
app.MainLoop()
这个应用会显示一个窗口,里面有一个大按钮。按下这个按钮后,预期的输出是:
Binding works
Messaging works
但实际上我得到的是:
Binding works
有没有人知道怎么解决这个问题?
1 个回答
4
你需要保存一个对控制器的引用,否则这个对象会被垃圾回收(GC),到发送消息时就不存在了。把倒数第二行改成:
controller = Controller(app)