2010-11-22 15 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と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 

誰もがこの問題を解決する方法を知っていますか?

答えて

4

コントローラへの参照を保存する必要があります。そうしないと、オブジェクトはGCになり、メッセージが送信されるまで存在しません。 2行目から最後の行を次のように変更します。

controller = Controller(app) 
+0

ニーススポット! wxPythonの例を更新して、誰も同じトラップにならないようにしました。すべてのあなたの歴史が愉快で、すべての道が平らで真っ直ぐになればよろしいですか? – kikito

関連する問題