2010-11-22 21 views
1

我正在使用wxPyton实施MVC应用程序,并且我遇到wx.lib.pubsub.Publisher问题。python - wx.lib.pubsub.Publisher在按下按钮调用时不工作?

我想保持我的控制器与我的视图尽可能分开。例如,我不希望我的控制器“知道”视图中使用的按钮的名称。在wxPython example上,控制器必须知道它们,因此它可以将操作绑定到它们。

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和2.8 wxPython的测试吧)

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 

有谁知道如何解决这个问题?

回答

4

您需要保存对您的控制器的引用,否则该对象获取GC'd,因此在发送消息时不存在。将倒数第二行更改为:

controller = Controller(app) 
+0

不错的斑点!我已经更新了wxPython示例,所以没有人会陷入同一个陷阱。愿你所有的历史都快乐起来,并且你所有的道路都平坦而直立。 – kikito 2010-11-22 15:56:17