web-dev-qa-db-ja.com

Python GUIおよびMVC-他のモジュールから変数を取得

コードをさまざまなレイヤーに分割しようとしています。GUI、GUIの読み取り、入力の作成、モデルの計算、データの解釈、ビューの作成、ビューのGUIへの送信です。誰かがMVCについて教えてくれたので、その方法でプログラムを構築したいと思います。しかし、これらのモジュール間で情報を交換する方法について少し混乱しています。未定義のグローバル名などの問題が発生しています。私のモデルはMATLABで書かれており、シミュレーションで構成されています。 GUIはデータをプロットで表示することになっています。

私の実際の問題は、可能な限り独立しているはずの場合に、異なるモジュール/クラス/ファイルを相互に接続する方法ですか?

たとえば、次のように1つのファイルでGUIを作成しています。

# userinterface.py

class Userinterface(object):
    def __init__(self, controller):
        self.controller = controller
        self.buildGUI()
        return

    def buildGUI():
        # build lots of widgets and stuff
        widget = tk.Thewidget(options=values, command=self.controller.onclick)

そして、それを私のインターフェースと呼んでください。このファイルをきれいに保つために、ボタンのクリックを処理し、別のファイルのフィールドを読み取るためのすべての関数を定義したいと思います。これがコントローラーパーツと呼ばれるものです。

# main.py
    import userinterface as gui

    class Controls(object):
        def onclick(self):
            # read values from widgets and do stuff
            var1 = GUI.widget_entry.get()
            # Call some other function with var1 etc.

if __name__ == '__main__':
    GUI_controls = Controls()
    GUI = gui.UserInterface(GUI_controls)

しかし、これら2つを接続するにはどうすればよいですか?上記の例では、Controlsオブジェクトのインスタンスを渡しています。しかし、それから私もイベントや継承やサブクラスについて読みました。

私はプログラミングにかなり慣れていないため、この2か月前にすべてを始めたので、これらすべての理論の分類に苦労しています。

誰かが私のモジュール/ファイル間の通信の方法と、そのようなミーティングポイントがどのように見えるかを私に指摘することができるなら。または、私が勉強できるリンクを教えてください(Javierがしたように、これを何度も読む必要があります)

4
lyvic

あなたは正しい軌道に乗っています。コントローラはアプリをバインドするものであるため、さまざまなビューやモデルクラスに渡して問題ありません。

ただし、コントローラーがあるからといって、すべてのウィジェットがすべてにコントローラーを使用する必要があるとは考えないでください。たとえば、コントローラにonclickメソッドを配置しません。コントローラーはビジネスロジックをルーティングするためのものですが、実行していることはほとんどGUIに固有です。

一般的な経験則として、GUIイベントとコールバックはGUIモジュール内にあるべきだと思います。次に、ビジネスロジックとのインターフェース時にコントローラーを呼び出します。 GUI自体から文字列をフェッチすることはビジネスロジックではありません。

したがって、代わりに:

_# GUI module
button = Button(..., command=controller.on_click)

# Controller module
def on_click():
    var1 = GUI.widget_entry.get()
    self.do_something(var1)
_

私はこれを行います:

_# GUI module
button = Button(..., command=on_click)
def on_click():
    var1 = widget_entry.get()
    controller.do_something(var1)
_

上記の場合、コントローラーは、どのウィジェットがGUIの一部であるかを知る必要はありません。 GUIがサービスを要求できるインターフェースを提供するだけです。

コントローラに_on_click_を保持したい場合は、それも可能であり、完全に不合理ではありません。ただし、GUIウィジェットの知識をコントローラーに組み込む代わりに、コントローラーが使用できるインターフェースをGUIに提供します。

たとえば、コントローラはGUI.widget_entry.get()を実行する代わりに、GUI.get_entry_widget_value()などのアクセサを呼び出します。これにより、コントローラーを変更せずにGUIをリファクタリングできます。エントリを_the_widget_entry_ではなく_widget_entry_に移動すると、コントローラは完全に認識されず、適切に機能します。

4
Bryan Oakley