Pack ジオメトリマネージャ
メインページ>コンピュータの部屋#Python>Tkinter Tips
Tkinterにはウィジェットをウィンドウ上に配置するための「ジオメトリマーネジャ」があります。 ジオメトリマネージャとは、ウィジェットの位置や大きさを決定する仕掛けです。
TkInterには Pack, Grid, Place の3種類のジオメトリマネージャがありますが、この記事では Pack ジオメトリマネーを紹介します。
Pack ジオメトリマネージャとは?
Pack ジオメトリマネージャとは、ウィジェットを「積んで」配置してゆくタイプのジオメトリマネージャです。所謂エラスティックなGUIデザインを実現してくれます。 言葉で説明するのは難しいので図を使って説明しましょう。
pack()メソッドを使ってみる
まず最初は最も簡単なコードを紹介しましょう。ウィンドウ全面に貼られた FrameウィジェットにButtonを貼り付けてみます。
import tkinter as tk root = tk.Tk() frame = tk.Frame(root, width=200, height=200) frame.pack_propagate(False) frame.pack() tk.Button(frame, text="A").pack() root.mainloop()
これを実行すると、こんな感じになります。
このコードでは pack() メソッドの動きが分かりやすくなるように、ちょっとしたおまじないのコードを使っています。
frame.pack_propagate(False)
は
tk.Button(frame, text="A").pack()
の影響が Frameウィジェットに及ぶのを防ぐためのコードです。このコードがないと、 Frameのサイズは Buttonウィジェットを表示するのに必要な最小限のサイズに自動的にリサイズします。
frame.pack_propagate(False)
としておくと、Frameウィジェットの大きさは コンストラクタに渡した width, height パラメータの値のままに保たれます。
ここで何が起きているかを簡単に説明しておきましょう。
tk.Button(frame, text="A").pack()
を実行すると、Buttonウィジェットは frameウィジェットの上端に張り付きます。
図の黄色いところは「Packメソッドによって ButtonウィジェットがFrameウィジェット上に確保したエリア」です。 これは、Buttonウィジェットのサイズとは異なることに注意してください。 「Packメソッドによって ButtonウィジェットがFrameウィジェット上に確保したエリア」はFrameオブジェクトの最上端に、Buttonウィジェットのテキストを表示するのに必要なだけの高さが確保され、横方向はFrameの横方向全体が確保されます。Buttonは確保されたエリアの「中央」に表示されるのです。
packメソッドを2つ使ってみる
これまで
tk.Button(frame, text="A").pack()
というコードでButtonウィジェットを配置してきましたが、実はこれは
tk.Button(frame, text="A").pack(side=tk.TOP)
と同じです。side=tk.TOP は親ウィジェットの上端にウィジェットを配置することを意味します。 ではこれを2回連続して使ったらどうなるでしょうか?
import tkinter as tk root = tk.Tk() frame = tk.Frame(root, width=200, height=200) frame.pack_propagate(False) frame.pack() tk.Button(frame, text="A").pack(side=tk.TOP) tk.Button(frame, text="B").pack(side=tk.TOP) root.mainloop()
を実行すると、下図のように縦積みになって表示されます。
これはつまり、Buttonウィジェットが下図のように自身を表示するエリアを確保するからです。
つまり2番目のButtonウェイジェットは1番目のボタンウィジェットで確保されたエリアを除いた部分のFrameウィジェットのエリアの最上端を確保するのです。
side=tk.LEFT を使ってみる
さてここまでは side=tk.TOP だけ使ってきましたが size=tk.Left と組み合わせてみましょう。
import tkinter as tk root = tk.Tk() frame = tk.Frame(root, width=200, height=200) frame.pack_propagate(False) frame.pack() tk.Button(frame, text="A").pack(side=tk.TOP) tk.Button(frame, text="B").pack(side=tk.LEFT) root.mainloop()
を実行すると、下図のように、今度は BボタンがFrameウィジェットの左側に貼り付いて表示されます。
BボタンはFrameウィジェットの左側に張り付いてますが、少し縦中央より下に表示されていることにお気づきでしょうか? このずれは以下の図を見ればわかります。