NMT Tkinter 8.5リファレンス の最小限の例を見たとき、私はTkinterをブラッシュアップしていました。
_#!/usr/bin/env python
import tkinter as tk
class Application(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.grid()
self.createWidgets()
def createWidgets(self):
self.quitButton = tk.Button(self, text='Quit',command=self.quit)
self.quitButton.grid()
app = Application()
app.master.title('Sample application')
app.mainloop()
_
Tk
クラスが初期化されていないことに気付くまでは、すべて問題ありません。私が見つけた他のオンラインリファレンス資料( Pythonのライブラリリファレンス 、 effbot.org 、 TkDocs )では、通常、root = tk.Tk()
、これから残りの例が構築されます。また、NMTの参照のどこにも、Tk
クラスの初期化への参照はありませんでした。
Tk
クラスに関して私が得ることができる情報もあいまいで、Pythonリファレンスはそれを「トップレベルウィジェット...通常はメインウィンドウである」としてのみリストしています。最後に、前に示したスニペットの最後の行を置き換えると、次のようになります。
_root = tk.Tk()
app = Application(root)
_
プログラムは以前と同じように実行されます。これらすべてを念頭に置いて、私が知りたいのは次のとおりです。
root = tk.Tk()
の呼び出しは実際に何をしますか(初期化されるもののように)、なぜ前のスニペットはそれなしで機能するのですか?Tk()
を呼び出さず、Frame
クラスを中心にアプリケーションを構築した場合、落とし穴や制限が発生しますか?Tkinterは、内部でtcl/tkインタープリターを起動し、tkinterコマンドをtcl/tkコマンドに変換することで機能します。メインウィンドウとこのインタープリターは本質的にリンクされており、tkinterアプリケーションが機能するには両方が必要です。
Tk
のインスタンスを作成すると、このインタープリターが初期化され、ルートウィンドウが作成されます。明示的に初期化しない場合、最初のウィジェットを作成するときに暗黙的に作成されます。
自分で初期化しないことによる落とし穴はないと思いますが、pythonの禅が述べているように、「明示的は暗黙的よりも優れています」。コードを理解するのは少し簡単です。 Tk
のインスタンスを明示的に作成します。これにより、たとえば、他の人があなたのコードについて、この他のコードについて尋ねたのと同じ質問をするのを防ぐことができます。
Bryan Oakley's 答えは的確です。ウィジェットを作成すると、暗黙的にtcl/tkインタープリターのインスタンスが作成されます。ただし、Tkが暗黙的に作成される方法をよりよく理解するために、いくつかのコードを追加したいと思います。
ウィジェットオブジェクトが作成されるたびに(フレーム、ボタン、またはttkベースのウィジェットであるかどうかに関係なく)、BaseWidget
クラスの___init__
_メソッドが呼び出され、次に__setup
_ 方法。関連する部分の抜粋は次のとおりです。
_def _setup(self, master, cnf):
"""Internal function. Sets up information about children."""
if _support_default_root:
global _default_root
if not master:
if not _default_root:
_default_root = Tk()
master = _default_root
self.master = master
self.tk = master.tk
_
__support_default_root
_と__default_root
_はどちらもグローバル変数であり、tkinter
パッケージの___init__.py
_ファイルの132〜133行で宣言されています。これらは次の値に初期化されます。
__support_default_root = 1
_default_root = None
_
これは、master
が提供されておらず、インタープリターがまだ作成されていない場合、Tk
のインスタンスが作成され、将来のすべてのウィジェットのデフォルトルートとして割り当てられることを意味します。
Tk
クラスのインスタンスを作成するときにも興味深いことがあります。次のスニペットは、_Tk._loadtk
_メソッドからのものです。
_if _support_default_root and not _default_root:
_default_root = self
_
つまり、Tk
クラスの初期化方法に関係なく、常にデフォルトのルートとして設定されます。