python - wx.lib.pubsub.Publisher не работает при вызове из нажатых кнопок? - PullRequest
1 голос
/ 22 ноября 2010

Я реализую приложение 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

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

1 Ответ

4 голосов
/ 22 ноября 2010

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

controller = Controller(app)
...