2010-11-22 29 views
1

J'applique une application MVC en utilisant wxPyton, et j'ai un problème avec wx.lib.pubsub.Publisher. Je souhaite que mon contrôleur soit aussi séparé de ma vue que possible. Par exemple, je ne veux pas que mon contrôleur «connaisse» les noms des boutons utilisés dans la vue. Sur le wxPython example, le contrôleur doit les connaître, afin qu'il puisse lier des actions à eux.Python - wx.lib.pubsub.Publisher ne fonctionne pas lorsqu'il est appelé à partir de boutons enfoncés?

class Controller: 
... 
self.view2.add.Bind(wx.EVT_BUTTON, self.AddMoney) 
self.view2.remove.Bind(wx.EVT_BUTTON, self.RemoveMoney) 

Je pensais que des choses « découplage » un peu plus, en utilisant à la place wx.lib.pubsub.Publisher messages:

from wx.lib.pubsub import Publisher as pub 

class Controller: 
... 
pub.subscribe(self.AddMoney, "MONEY ADDED") 
pub.subscribe(self.RemoveMoney, "MONEY REMOVED") 

La vue lierait les contrôles à une action qui vient d'envoyer les messages.

Mais hélas, cela ne semble pas fonctionner. Soit la vue refuse d'envoyer des événements, soit le contrôleur refuse de recevoir des messages de la vue. Je ne suis pas sûr.

est ici une application petit échantillon qui illustre mon problème (je l'ai testé avec python 2.6.6 et 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() 

L'application affiche une fenêtre avec un gros bouton. Le résultat attendu après avoir appuyé sur il est:

Binding works 
Messaging works 

Mais au lieu je reçois:

Binding works 

Est-ce que quelqu'un sait comment résoudre ce problème?

Répondre

4

Vous devez enregistrer une référence à votre automate, sinon l'objet sera GC'd et n'existera donc pas au moment où le message est envoyé. Changez l'avant-dernière ligne à:

controller = Controller(app) 
+0

Nice spotting! J'ai mis à jour l'exemple wxPython pour que personne d'autre ne tombe dans le même piège. Puissent toutes tes histoires être joyeuses, et tous tes chemins plats et droits. – kikito