Pythonでtkinter GUIをプログラミングするときにクラスを使用する理由


19

私は主にPythonでプログラミングし、TkinterでいくつかのGUIをプログラミングしました。これまでに見たすべてのチュートリアルでは、GUIのクラスを定義して使用することを推奨していますが、GUIはクラスなしで手順のみを使用して問題なく実行されます。

クラスを使用する理由 私の観点からは、単純に余分な複雑なレイヤーと不要なコードであるように思えます。

回答:


19

クラスを使用する理由 オブジェクト指向プログラミングの方法を知っていると仮定し、非自明なGUIを書いていると仮定すると、作業が簡単になるためです。オブジェクトを使用すると、コードを自己完結型のモジュール単位に簡単に分割できます。コードをモジュール化することは、一般的にベストプラクティスと見なされています。

GUIはすべてラベル、ボタン、スクロールバー、テキスト領域などのオブジェクトで構成されているため、GUIプログラミングはすぐにオブジェクト指向スタイルになります。すでにオブジェクトを使用しているので、コードをより大きなオブジェクトに整理することは理にかなっています。ツールバーはオブジェクト、ステータスバーはオブジェクト、ナビゲーションペインはオブジェクト、メインエリアはオブジェクト、各ノートブックタブはオブジェクトなどです。

コードがそれほど複雑ではない場合でも、より実用的な観点から、呼び出している関数の定義よりもファイル内でバインディングとコールバックを早く定義できます。これは非常に理にかなっていると思います。

たとえば、単純な例を考えますimport tkinter as tk(tkinter が(python3)またはimport Tkinter as tk(python2)のようにインポートされていると仮定します)。

def quit(event=None):
    sys.exit()
root = tk.Tk()
label = tk.Label(root, text="Hello, world")
label.pack()
label.bind("<1>", quit)
root.mainloop()

私にとって、そのコードの流れはすべて間違っています。参照する前にquitメソッドを定義する必要があり、ルートウィンドウの作成とメインループの呼び出しは、他のすべてのコードによって分離されています。

ただし、クラスを使用すると、より自然な順序でコードを記述できます。

class MyWindow(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text="Hello, world")
        label.pack()
        label.bind("<1>", self.quit)
    def quit(self, event=None):
        sys.exit()

root = tk.Tk()
MyWindow(root).pack()
root.mainloop()

GUIの本体はファイルの一番上にあり、サポートコードはその下にあります。これで、もちろん、関数を使用してほぼ同じことを実現できます。私の意見では、しかし、クラスはそれをすべて少しだけ簡単にします。

もう1つの利点は、「メイン」ウィンドウ(およびその逆)について何も変更することなく、格納ウィンドウを簡単に変更できることです。つまり、メインGUIに境界線または完全に新しいセクションを追加できますが、MyWindow内の1行のコードに触れる必要はありません。label.pack()ステートメントと、UI内の他のすべてのウィジェットのパック(またはグリッド)ステートメントを変更する必要がある場合がある手順コードとは対照的です。

ただし、オブジェクト指向のアプローチを使用するということは、優れたクリーンで保守可能なコードを書くために必要なことではありません。それはできること、それはまた、貧しい人々のコードにつながることができます。結局のところ、オブジェクト指向のアプローチは単なるツールにすぎません。使用するかどうか、正しく使用するかどうかは多くの要因に依存します。だから、あなたにとって、そしてあなたが書くコードにとって、機能的なスタイルは完全に受け入れられるということです。プログラムがより複雑になると、オブジェクト指向のアプローチによりコードの整理と保守が容易になることがわかると思います。


なぜ2番目の例でフレームを使用したのですか?最初の例でやったようにそれを避けることができませんでしたか?クラスでフレームを使用する背後に秘密がありますか?
-multigoodverse

2
フレームは単に便宜上のものです。フレームから継承する秘密はありません。objectまたは他のクラスを継承することもできましたが、通常はとにかくフレームを作成することになります。すべてをフレームに入れる場合、クラスをフレームにすることは理にかなっています。。
ブライアンオークリー

1
理にかなっています、ありがとう!また、変数の前にselfを使用する人もいますが、のlabel=tk.Label()代わりにを使用しているよう ですself.tk.Label()。それはスタイルの選択ですか?:ここでは、自己の使用例であるpython-textbok.readthedocs.org/en/1.0/...
multigoodverse

1
@ BryanOakley、MyWindow .__ init__の次の行でrootの代わりに親を使用するつもりだったと思います: "label = tk.Label(root、text =" Hello、world ")"
user3885927

1
@ user3885927:はい!うわー、誰かがそれに気づくのにほぼ3年かかった。parentただしself、クラス自体はフレームなので、むしろではありません。ありがとう!
ブライアンオークリー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.