Tkinter: gridメソッドで余白をウィジェットに割り当てる

Tkinterを用いたGUIアプリケーション開発では,tkinter.Labelやtkinter.Entry等のウィジェットを配置するため,packメソッドやgridメソッドを利用します。

ウェブ検索結果ではgirdメソッドを用いた配置の際に,stickyオプションを指定することでウィンドウ(あるいはtkinter.Frame)の余白を所定のウィジェットに割り当てることができると紹介されていますが,実際はこの操作だけでは不十分です(packメソッドを用いる場合はfillオプション指定で十分)。

このページでは,gridメソッドを用いてウィジェットを配置する際に余白を割り当て,ウィジェットを任意の方向に伸縮可能な状態で配置する方法について紹介します。

パッケージのインポート

このページでは「tkinter」パッケージを「tk」としてインポートしています。pythonバージョンは3.7.9です。

import tkinter as tk

単純なgridメソッド

gridメソッドの動作確認のため,ウィンドウサイズを200×200に指定した状態で,0行0列目にラベルを配置しています。

root = tk.Tk()
root.geometry('200x200')
tk.Label(root, text='row=0, column=0', bg='green').grid(row=0, column=0)
root.mainloop()
ラベル表示に必要な領域にのみウィジェットが配置されており,上下左右の余白は利用されていない

stickyオプションを指定

gridメソッドのstickyオプションを「sticky=tk.EW」とすることで左右方向にウィジェットが引き伸ばされ,「sticky=tk.NS」で上下方向,「sticky=NSEW」で上下左右方向にウィジェットが引き伸ばされると紹介するものもあります。しかし,下記画像の通りウィジェットは引き伸ばされないのが実際です

# sticky=tk.EWで左右引き伸ばし
root = tk.Tk()
root.title('tk.EW')
root.geometry('200x200')
tk.Label(root, text='row=0, column=0', bg='green').grid(row=0, column=0, sticky=tk.EW)
root.mainloop()

# sticky=tk.NSで上下引き伸ばし
root = tk.Tk()
root.title('tk.NS')
root.geometry('200x200')
tk.Label(root, text='row=0, column=0', bg='green').grid(row=0, column=0, sticky=tk.NS)
root.mainloop()
ラベル表示に必要な領域にのみウィジェットが配置されており,上下左右の余白は利用されていない

columnconfigurerowconfigureを指定

実際にウィジェット配置に余白を割り当てようとした場合には,stickyオプションの指定に加えて,配置するフレームの行方向(row)・列方向(column)の引き伸ばし設定をconfigureからする必要があります。

今回はrootのフレーム上にウィジェットを配置しているため,root.columnconfigure()で列方向(左右方向)root.rowconfigure()で行方向(上下方向)の引き伸ばし設定が行えます。

columnconfigure: 左右方向の引き伸ばし

下記の例では,tk.Labelウィジェットは0列目(column=0)で配置するので,root.columnconfigure() の第一引数は余白を割り当てたい列にあたる「0」を与えます。weightはウィジェットに割り当てる余白の割合に相当する引数ですが,詳細は後述します。ここでは「weight=1」を指定します。stickyオプションの指定を忘れないようにしましょう(sticky=tk.EW)

root = tk.Tk()
root.geometry('200x200')
root.columnconfigure(0, weight=1)
tk.Label(root, text='row=0, column=0', bg='green').grid(row=0, column=0, sticky=tk.EW)
root.mainloop()
左右方向の余白がtk.Labelウィジェットに割り当てられた

rowconfigure: 上下方向の引き伸ばし

上下方向の引き伸ばし例は下記のとおりです。tk.Labelウィジェットは0行目(row=0)に配置されているので,root.rowconfigure() の第一引数には余白を割り当てたい行にあたる「0」を与えます。weightオプションは「1」を指定します。stickyオプションの指定を忘れないようにしましょう(sticky=tk.NS)

root = tk.Tk()
root.geometry('200x200')
root.rowconfigure(0, weight=1)
tk.Label(root, text='row=0, column=0', bg='green').grid(row=0, column=0, sticky=tk.NS)
root.mainloop()
上下方向の余白がtk.Labelウィジェットに割り当てられた

columnconfigure/rowconfigure: 上下左右方向の引き伸ばし

上下左右に引き延ばしを行いたい場合は,columnconfigure/rowconfigure 双方を指定します。stickyオプション指定を忘れないように注意しましょう(sticky=tk.NSEW)

root = tk.Tk()
root.geometry('200x200')
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
tk.Label(root, text='row=0, column=0', bg='green').grid(row=0, column=0, sticky=tk.NSEW)
root.mainloop()
上下左右方向全ての余白がtk.Labelに割り当てられた

weightオプションを指定

gridメソッドで複数配置されたウィジェットに対して,行・列ごとに割り当てる余白の割合を指定したい場合にweightオプションを利用します。

例えば,2×2配置されたウィジェットに対して,1列目のウィジェットと比較して0列目のウィジェットに2倍の余白を割り当てたい場合には,0列目のcolumnconfigureのweightオプションを「2」に指定します。

同様に,1行目のウィジットと比較して0行目のウィジェットに3倍の余白を割り当てたい場合には,0行目のronconfigureのweightオプションを「3」に指定します。

root = tk.Tk()
root.geometry('300x400')
root.columnconfigure(0, weight=2)
root.columnconfigure(1, weight=1)
root.rowconfigure(0, weight=3)
root.rowconfigure(1, weight=1)
tk.Label(root, text='row=0, column=0', bg='green', fg='white').grid(row=0, column=0, sticky=tk.NSEW)
tk.Label(root, text='row=0, column=1', bg='red', fg='white').grid(row=0, column=1, sticky=tk.NSEW)
tk.Label(root, text='row=1, column=0', bg='blue', fg='white').grid(row=1, column=0, sticky=tk.NSEW)
tk.Label(root, text='row=1, column=1', bg='yellow', fg='black').grid(row=1, column=1, sticky=tk.NSEW)
root.mainloop()
weightオプションを指定して余白割り当て割合を行列で操作した結果,各ウィジェット表示領域が変化した

最後に

ウィジェットを配置するフレームのcolumnconfigure/rowconfigureを設定することで,girdメソッドを用いたウィジェット配置の引き伸ばし設定をすることができました。

さらに,weightオプションを指定することで複数ウィジェット間の余白割り当て割合を操作することができます。余白割り当て設定を操作することで,ウィンドウサイズが変更された場合であっても動的にウィジェットサイズが変更されるようになります。

ここでは主にcolumnconfigure/rowconfigureの設定について述べましたが,これらの設定をしてもgirdメソッドのstickyオプションで引き伸ばし方向を指定しなければ,余白割り当てが行われない点に注意してください。

それでは楽しいGUIアプリケーション開発ライフを。

コメント