179

以下は、私の典型的な python tkinter プログラムの全体的な構造です。

def funA():
    def funA1():
        def funA12():
            # stuff

    def funA2():
        # stuff

def funB():
    def funB1():
        # stuff

    def funB2():
        # stuff

def funC():
    def funC1():
        # stuff

    def funC2():
        # stuff


root = tk.Tk()

button1 = tk.Button(root, command=funA)
button1.pack()
button2 = tk.Button(root, command=funB)
button2.pack()
button3 = tk.Button(root, command=funC)
button3.pack()

funA funBユーザーがボタン 1、2、3 をクリックすると、ウィジェットを含む別のウィンドウが表示され ますfunCToplevel

これがpython tkinterプログラムを書く正しい方法であるかどうか疑問に思っていますか? 確かに、このように書いても動作しますが、それが最善の方法でしょうか? ばかげているように聞こえますが、他の人が書いたコードを見ると、彼らのコードはたくさんの関数でめちゃくちゃになっておらず、ほとんどの場合クラスがあります。

グッドプラクティスとして従うべき特定の構造はありますか? Python プログラムの作成を開始する前に、どのように計画すればよいですか?

プログラミングにはベスト プラクティスなどというものがないことはわかっていますし、それを求めているわけでもありません。私は自分でPythonを学んでいるので、正しい方向に進むためのアドバイスと説明が欲しいだけです.

4

8 に答える 8

357

私はオブジェクト指向のアプローチを提唱しています。これは私が最初に使用するテンプレートです。

# Use Tkinter for python 2, tkinter for python 3
import tkinter as tk

class MainApplication(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)
        self.parent = parent

        <create the rest of your GUI here>

if __name__ == "__main__":
    root = tk.Tk()
    MainApplication(root).pack(side="top", fill="both", expand=True)
    root.mainloop()

注意すべき重要事項は次のとおりです。

  • ワイルドカード インポートは使用しません。パッケージを「tk」としてインポートします。これには、すべてのコマンドの前にtk.. これにより、グローバルな名前空間の汚染が防止され、さらに、Tkinter クラス、ttk クラス、または独自のものを使用しているときにコードが完全に明確になります。

  • 主なアプリケーションはクラスです。これにより、すべてのコールバックとプライベート関数のプライベート名前空間が提供され、一般的にコードの整理が容易になります。手続き型のスタイルでは、トップダウンでコーディングし、関数を使用する前に定義する必要があります。この方法では、最後のステップまで実際にメイン ウィンドウを作成しないため、必要ありません。通常はフレームの作成から開始するという理由だけで、からの継承を好みtk.Frameますが、それは決して必要ではありません。

アプリに追加のトップレベル ウィンドウがある場合は、tk.Toplevel. これにより、上記と同じ利点がすべて得られます。ウィンドウはアトミックであり、独自の名前空間があり、コードは適切に編成されています。さらに、コードが大きくなり始めたら、それぞれを独自のモジュールに簡単に配置できます。

最後に、インターフェイスのすべての主要部分にクラスを使用することを検討することをお勧めします。たとえば、ツールバー、ナビゲーション ペイン、ステータスバー、およびメイン領域を備えたアプリを作成している場合、これらのクラスをそれぞれ 1 つ作成できます。これにより、メイン コードが非常に小さくなり、理解しやすくなります。

class Navbar(tk.Frame): ...
class Toolbar(tk.Frame): ...
class Statusbar(tk.Frame): ...
class Main(tk.Frame): ...

class MainApplication(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)
        self.statusbar = Statusbar(self, ...)
        self.toolbar = Toolbar(self, ...)
        self.navbar = Navbar(self, ...)
        self.main = Main(self, ...)

        self.statusbar.pack(side="bottom", fill="x")
        self.toolbar.pack(side="top", fill="x")
        self.navbar.pack(side="left", fill="y")
        self.main.pack(side="right", fill="both", expand=True)

これらのインスタンスはすべて共通の親を共有するため、親は事実上、モデル ビュー コントローラー アーキテクチャの「コントローラー」部分になります。したがって、たとえば、メイン ウィンドウは を呼び出してステータスバーに何かを配置できますself.parent.statusbar.set("Hello, world")。これにより、コンポーネント間のシンプルなインターフェースを定義でき、最小限の結合を維持するのに役立ちます。

于 2013-07-04T12:52:50.853 に答える
47

各トップレベル ウィンドウを独自の個別のクラスに配置すると、コードの再利用とコードの編成が向上します。ウィンドウに表示されるすべてのボタンと関連メソッドは、このクラス内で定義する必要があります。例を次に示します (ここから取得):

import tkinter as tk

class Demo1:
    def __init__(self, master):
        self.master = master
        self.frame = tk.Frame(self.master)
        self.button1 = tk.Button(self.frame, text = 'New Window', width = 25, command = self.new_window)
        self.button1.pack()
        self.frame.pack()
    def new_window(self):
        self.newWindow = tk.Toplevel(self.master)
        self.app = Demo2(self.newWindow)

class Demo2:
    def __init__(self, master):
        self.master = master
        self.frame = tk.Frame(self.master)
        self.quitButton = tk.Button(self.frame, text = 'Quit', width = 25, command = self.close_windows)
        self.quitButton.pack()
        self.frame.pack()
    def close_windows(self):
        self.master.destroy()

def main(): 
    root = tk.Tk()
    app = Demo1(root)
    root.mainloop()

if __name__ == '__main__':
    main()

以下も参照してください。

それが役立つことを願っています。

于 2013-07-04T09:40:36.723 に答える
-4

おそらく、自分のプログラムをどのように構築するかを学ぶ最良の方法は、他の人のコードを読むことです。それが多くの人が貢献した大きなプログラムの場合は特にそうです。多くのプロジェクトのコードを見た後、コンセンサス スタイルがどうあるべきかのアイデアを得る必要があります。

言語としての Python は、コードをどのようにフォーマットするべきかについていくつかの強力なガイドラインがあるという点で特別です。1 つ目は、いわゆる「Zen of Python」です。

  • 美しいことは醜いことよりも優れています。
  • 明示的は暗黙的よりも優れています。
  • シンプルは複雑よりも優れています。
  • 複雑は複雑よりも優れています。
  • フラットはネストよりも優れています。
  • 疎は密よりも優れています。
  • 読みやすさが重要です。
  • 特別なケースは、ルールを破るほど特別なものではありません。
  • 実用性は純粋さに勝りますが。
  • エラーは黙って通過するべきではありません。
  • 明示的に黙らせない限り。
  • あいまいさに直面しても、推測する誘惑を断ってください。
  • それを行う明白な方法が 1 つ (できれば 1 つだけ) ある必要があります。
  • あなたがオランダ人でない限り、その方法は最初は明白ではないかもしれませんが.
  • 今は決してないよりはましです。
  • 多くの場合、今よりも良くなることはありませんが。
  • 実装を説明するのが難しい場合、それは悪い考えです。
  • 実装が説明しやすい場合は、良い考えかもしれません。
  • 名前空間は素晴らしいアイデアの 1 つです。もっと多くのことをしましょう!

より実用的なレベルでは、Python のスタイル ガイドであるPEP8があります。

これらを念頭に置いて、あなたのコードスタイル、特にネストされた関数は実際には適合していないと思います。クラスを使用するか、それらを別のモジュールに移動することにより、それらをフラット化する方法を見つけてください。これにより、プログラムの構造が理解しやすくなります。

于 2013-07-04T09:36:34.517 に答える