ウィジェットを配置するには、pack,grid,placeの3つのメソッドがありますが、ここではgridについて説明します。
gridでウィジェットを配置するのは、どことなくエクセルのセルにウィジェットを配置するようなイメージに似ています。
こんなイメージ↓
ただし、gridでは行番号(row)、列番号(column)は0(ゼロ)から始まります。
また、エクセルにはセルを結合して中央揃えという機能がありますが、gridにも同様の機能があり、rowspan、columnspanを使ってセルを結合します。
最初のエクセルのイメージで配置したプログラムがこちら↓(ウィジェットの範囲が分かり易いように背景色をつけました)
import tkinter as tk
class Application(tk.Frame):
def __init__(self, master = None):
super().__init__(master)
self.master.title("ウィジェットの配置(grid)") # ウィンドウタイトル
self.master.geometry("300x180") # ウィンドウサイズ(幅x高さ)
#--------------------------------------------------------
# ラベルの作成
label1 = tk.Label(self.master, text = "ラベル1", bg = 'cyan1')
label2 = tk.Label(self.master, text = "ラベル2", bg = 'green1')
label3 = tk.Label(self.master, text = "ラベル3", bg = 'yellow1')
label4 = tk.Label(self.master, text = "ラベル4", bg = 'pink1')
label5 = tk.Label(self.master, text = "ラベル5", bg = 'MediumPurple1')
label6 = tk.Label(self.master, text = "***ラベル6***", bg = 'LightSteelBlue1')
#--------------------------------------------------------
# gridでウィジェットの配置
label1.grid(row = 0, column = 1, columnspan = 3, sticky = tk.W+tk.E)
label2.grid(row = 0, column = 0, rowspan = 5, sticky = tk.N+tk.S)
label3.grid(row = 1, column = 1)
label4.grid(row = 1, column = 3)
label5.grid(row = 2, column = 2)
label6.grid(row = 3, column = 1, columnspan = 3)
#--------------------------------------------------------
if __name__ == "__main__":
root = tk.Tk()
app = Application(master = root)
app.mainloop()
構文
ウィジェット.grid(オプション1 = 設定値, オプション2 = 設定値,・・・)
オプション
オプション名 | 説明 |
column | ウィジェットを配置する列番号(0始まり)を指定します。 |
columnspan | グリッドを横方向に結合する数を指定します。 |
ipadx | ウィジェットの内側の横方向の隙間を設定します。 |
ipady | ウィジェットの内側の縦方向の隙間を設定します。 |
padx | ウィジェットの外側の横方向の隙間を設定します。 |
pady | ウィジェットの外側の縦方向の隙間を設定します。 |
row | ウィジェットを配置する行番号(0始まり)を指定します。 |
rowspan | グリッドを縦方向に結合する数を指定します。 |
sticky | グリッド内のウィジェットを配置する位置 アンカーの機能にも似ていますが、例えば上下(tk.N+ tk.S)を指定すると、ウィジェットが上下方向にグリッド内いっぱいに広がります。【設定値】tk.N, tk.S, tk.W, tk.E, tk.NW, tk.NE, tk.SW, tk.SE, tk.NSEW および上記組み合わせ(tk.N+ tk.Sなど) |
ウィンドウのリサイズに合わせて行、列の幅、高さを調整する
gridでウィジェットを配置すると、行や列方向の最大の高さ、幅に合わせてグリッド状に配置されますが、ウィンドウをリサイズしても幅や高さが変わる事がありません。
↓ウィンドウのリサイズ
そこで、ウィンドウに合わせて行の高さを調整するにはgrid_rowconfigure()メソッドを、列の幅を調整するにはgrid_columnconfigure()メソッドを用います。
構文
親ウィジェット.grid_columnconfigure(列番号, オプション)
親ウィジェット.grid_rowconfigure(行番号, オプション)
オプション
オプション名 | 説明 |
weight | 1以上の整数を指定すると、幅/高さが調整されます。 複数の行もしくは列に対してweightを指定すると、指定したweightの値の比率で幅/高さが調整されます。 |
minsize | 最小の幅/高さを画素単位で指定します。 |
pad | 列/高さの隙間を画素単位で指定します。 |
サンプル
import tkinter as tk
class Application(tk.Frame):
def __init__(self, master = None):
super().__init__(master)
self.master.title("ウィジェットの配置(grid)") # ウィンドウタイトル
self.master.geometry("300x180") # ウィンドウサイズ(幅x高さ)
#--------------------------------------------------------
# ラベルの作成
lbl_00 = tk.Label(self.master, text = "row,col")
lbl_col1 = tk.Label(self.master, text = "col1")
lbl_col2 = tk.Label(self.master, text = "col2")
lbl_col3 = tk.Label(self.master, text = "col3")
lbl_row1 = tk.Label(self.master, text = "row1")
lbl_row2 = tk.Label(self.master, text = "row2")
lbl_row3 = tk.Label(self.master, text = "row3")
#--------------------------------------------------------
# Entry(テキストボックス)の作成
entry1 = tk.Entry(self.master, width = 20)
entry2 = tk.Entry(self.master, width = 20)
entry3 = tk.Entry(self.master, width = 20)
#--------------------------------------------------------
# ボタンの作成
button1 = tk.Button(self.master, text = "...")
button2 = tk.Button(self.master, text = "...")
button3 = tk.Button(self.master, text = "...")
#--------------------------------------------------------
# gridでウィジェットの配置
lbl_00.grid(row = 0, column = 0)
lbl_col1.grid(row = 0, column = 1)
lbl_col2.grid(row = 0, column = 2)
lbl_col2.grid(row = 0, column = 3)
lbl_row1.grid(row = 1, column = 0)
lbl_row2.grid(row = 2, column = 0)
lbl_row3.grid(row = 3, column = 0)
entry1.grid(row = 1, column = 1, sticky=tk.EW) # 幅に合わせて大きくする
entry2.grid(row = 2, column = 1, sticky=tk.EW) # 幅に合わせて大きくする
entry3.grid(row = 3, column = 1, sticky=tk.EW) # 幅に合わせて大きくする
button1.grid(row = 1, column = 3)
button2.grid(row = 2, column = 3)
button3.grid(row = 3, column = 3)
#--------------------------------------------------------
# ウィンドウのリサイズに合わせてEntryの幅(column=1)を広げる
self.master.grid_columnconfigure(1, weight=1) # 列の調整
#self.master.grid_rowconfigure(1, weight=1) # 行の調整
if __name__ == "__main__":
root = tk.Tk()
app = Application(master = root)
app.mainloop()
実行結果
↓ウィンドウのリサイズ
gridを使うサンプル
個人的にはウィンドウ内にFrameを配置し、その中にpackでウィジェットを配置する場合が多いのですが、gridはラベルとテキストボックス(Entry)を並べて配置する場合に使っています。
以下は、ラベルとテキストボックスを並べたサンプルです。
import tkinter as tk
class Application(tk.Frame):
def __init__(self, master = None):
super().__init__(master)
self.master.title("ウィジェットの配置(grid)") # ウィンドウタイトル
self.master.geometry("300x180") # ウィンドウサイズ(幅x高さ)
#--------------------------------------------------------
# ラベルの作成
label0 = tk.Label(self.master, text = "設定値")
label1 = tk.Label(self.master, text = "項目1")
label1_1 = tk.Label(self.master, text = "項目1_1")
label1_2 = tk.Label(self.master, text = "項目1_2")
label1_3 = tk.Label(self.master, text = "項目1_3")
label2 = tk.Label(self.master, text = "項目2")
label2_1 = tk.Label(self.master, text = "項目2_1")
label2_2 = tk.Label(self.master, text = "項目2_2")
label2_3 = tk.Label(self.master, text = "項目2_3")
# テキストボックス(Entry)の作成
self.entry1_1 = tk.Entry(self.master, justify = tk.RIGHT)
self.entry1_2 = tk.Entry(self.master, justify = tk.RIGHT)
self.entry1_3 = tk.Entry(self.master, justify = tk.RIGHT)
self.entry2_1 = tk.Entry(self.master, justify = tk.RIGHT)
self.entry2_2 = tk.Entry(self.master, justify = tk.RIGHT)
self.entry2_3 = tk.Entry(self.master, justify = tk.RIGHT)
#--------------------------------------------------------
# gridでウィジェットの配置
label0.grid(row = 0, column = 0, rowspan = 8)
label1.grid(row = 0, column = 1, columnspan = 2)
label1_1.grid(row = 1, column = 1); self.entry1_1.grid(row = 1, column = 2)
label1_2.grid(row = 2, column = 1); self.entry1_2.grid(row = 2, column = 2)
label1_3.grid(row = 3, column = 1); self.entry1_3.grid(row = 3, column = 2)
label2.grid(row = 4, column = 1, columnspan = 2)
label2_1.grid(row = 5, column = 1); self.entry2_1.grid(row = 5, column = 2)
label2_2.grid(row = 6, column = 1); self.entry2_2.grid(row = 6, column = 2)
label2_3.grid(row = 7, column = 1); self.entry2_3.grid(row = 7, column = 2)
#--------------------------------------------------------
if __name__ == "__main__":
root = tk.Tk()
app = Application(master = root)
app.mainloop()
(実行画面)
上記にある「ただし、gridでは行番号(row)、列番号(column)は0(ゼロ)から始まります。」という文章、正しくは「ただし、gridでは列番号(row)、行番号(column)は0(ゼロ)から始まります。」かと思うのですが、いかがでしょうか
rowは行、columnは列であっていませんか?
tkinterのウィジェットのは一方法が理解できず、いろいろなサイトを見てきましたが、グリッドで配置する方法を教えていただきとても助かりました。
直感的に操作できるようになりそうです
こまさん、コメント頂きありがとうございます。
ウィジェットの配置はFrameを組み合わせると、少し融通が利く配置が出来るようになりと思います。
これに関しては、packでの配置についての記事の最後に記載しているので、参考にしてみてください。
https://imagingsolution.net/program/python/tkinter/widget_layout_pack/