0

MVC で wxpython を使用して、モデルがコントローラーに変更を通知できるようにする方法を探しました。グローバルな通知メカニズムを実装する (py)pubsub を見つけました。メッセージは 1 つの場所 (pubsub Publisher) に送信され、そこからすべてのサブスクライバに送信されます。各サブスクライバーは、メッセージが興味深いかどうかを確認し、必要なことを行います。

Smalltalk の時代から、私はより「ローカルな」アプローチを知っています。各モデル オブジェクトは、関心のあるコントローラーのリストを保持し、変更通知のみをこれらのコントローラーに送信します。グローバルなパブリッシャーは関与していません。これは Model クラスの一部として実装でき、モデルとコントローラーに対してローカルであることを除いて、ほとんど同じように機能します。

グローバル アプローチを使用する理由はありますか? ローカル オブザーバーを実装する別のパッケージはありますか?

ありがとう!

4

2 に答える 2

0

ここでは微妙な違いはあまり見られません。私の知る限り、pubsub が最適です。wxPython の wx.lin.pubsub に含まれているか、 http://pubsub.sourceforge.net/からダウンロードできます。リスナーをモデルだけに、パブリッシャーをコントローラーだけに、または必要に応じて配置できます。開始するためのいくつかのリンクを次に示します。

于 2013-03-27T15:53:57.847 に答える
0

私は wxpython で MVC を実行するためにしばらく遊んでいましたが、pubsub がグローバルであることについてあなたが何を意味するかを知っています。

私が思いついた最新のアイデアは、各ビューとモデルに独自のオブザーバーがあることです。オブザーバーはハンドラーへの弱い参照を持ち、GUI をブロックしないようにすべて別のスレッドで動作します。GUI スレッドにコールバックするには、wxAnyThread Gui メソッド デコレータを使用しています。

送信されるシグナルには 3 つのタイプがあります。モデルでは、どの属性が監視されるかを設定でき、変更されたときに自動的にシグナルを送信します。次に、モデルとビューの両方で、メッセージ シグナルまたはキーワード シグナルを送信できます。3 つのシグナル タイプはそれぞれ、それらを識別するタプルを作成するために使用されるため、ビューまたはモデルごとに一意である必要があります。

モデル属性

コントローラハンドラはで装飾されています

@onAttr('attributeName')
def onModelAttributeName(self, attributeName)

属性をハンドラーするメソッドにバインドすると、現在の値でハンドラーがすぐに呼び出され、変更を監視し続けます。

メッセージの送信

メソッドを使用する

view/model.notify('Your message'):

コントローラーのコールバックは次のように装飾されています

@onNotify('Your message')
def onYourMessage(self):

キーワードの送信

メソッドを使用する

view/model.notifyKw(valid=True, value='this)

コントローラーのコールバックは次のように装飾されています

@onNotifyKw('valid', 'value')
def onValidValueKw(self, valid, value)

GUI はモデルについて何も知らずに残されます。GUI に追加する唯一のものはビュー シグナルです。コントローラーはそれ自体をこれに接続します。したがって、コントローラーを追加しない場合、ビューは喜んで誰にもメッセージを送信しません。 .

今までの内容をgithubにアップしました

https://github.com/Yoriz/Y_Signal

https://github.com/Yoriz/Y_Mvc

両方とも単体テストがあり、それが何をするかの例を少し示す必要がありますが、wxpython の例をいくつか作成します。

私はpythonバージョン2.7を使用しており、Ysignalsモジュール にはスレッド用にhttps://pypi.python.org/pypi/futures/2.1.3が必要です。他の誰かが mvc にアプローチするこの方法についてどう思うか、または私が真剣に見落としていることを指摘することに興味を持って見てください。

于 2013-03-28T00:18:55.897 に答える