python - wx.lib.pubsub.Publisher не работает при вызове с помощью нажатых кнопок?

Я реализую приложение MVC, используя wxPyton, и у меня проблема с 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

Кто-нибудь знает, как это решить?


person kikito    schedule 22.11.2010    source источник


Ответы (1)


Вам необходимо сохранить ссылку на ваш контроллер, в противном случае объект будет подвергнут сборке мусора и, следовательно, не будет существовать к моменту отправки сообщения. Измените предпоследнюю строку на:

controller = Controller(app)
person Bryan Oakley    schedule 22.11.2010
comment
Хорошее пятно! Я обновил пример wxPython, чтобы никто больше не попал в ту же ловушку. Пусть все ваши истории будут веселыми, и все ваши пути будут ровными и прямыми. - person kikito; 22.11.2010