ここでは、Tkinterのgrid
を初心者向けに徹底解説しています。
行・列・sticky・padding・row/columnconfigureとweight、columnspan/rowspan、よくあるエラー対処まで広く解説しています。
フォームや2カラムの実用テンプレ付きで、リサイズに強いGUIがすぐ作れます。
Tkinter grid の基本(仕組みと書式)
基本的な仕組みは、親ウィジェット(例:root
やFrame
)を表(グリッド)に見立てて、各ウィジェットを(row, column) のセルに配置します。
widget.grid(row=行番号, column=列番号)
行・列は0から始まります。
コツ:1つの親(同じroot
や同じFrame
)の中で grid
とpack
は混在しない ようにしましょう(混ぜると例外が出ます)。
使用例
例1: 基本的なグリッド配置
import tkinter as tk
root = tk.Tk()
label1 = tk.Label(root, text="Label 1")
label1.grid(row=0, column=0)
label2 = tk.Label(root, text="Label 2")
label2.grid(row=0, column=1)
root.mainloop()
解説:
この例では、2つのラベルウィジェットを作成し、それぞれを異なる列に配置しています。row=0
は両方のラベルが同じ行にあることを意味しています。
結果

例2: columnspan / rowspan でセルをまたぐ
import tkinter as tk
root = tk.Tk()
root.title("columnspan / rowspan")
label1 = tk.Label(root, text="Label 1 spans 2 columns", bg="#e0f7fa")
label1.grid(row=0, column=0, columnspan=2, sticky="nsew")
label2 = tk.Label(root, text="Label 2", bg="#f1f8e9")
label2.grid(row=1, column=0, sticky="nsew")
label3 = tk.Label(root, text="Label 3", bg="#fff3e0")
label3.grid(row=1, column=1, sticky="nsew")
root.mainloop()
解説:columnspan=2
で横に2セル分の幅を確保。rowspan
なら縦にまたいでいる例です。
結果

例3: padx / pady で外側の余白(マージン)
import tkinter as tk
root = tk.Tk()
root.title("padx/pady")
label1 = tk.Label(root, text="Label 1")
label1.grid(row=0, column=0, padx=10, pady=10)
label2 = tk.Label(root, text="Label 2")
label2.grid(row=0, column=1, padx=10, pady=10)
root.mainloop()
解説:padx
/pady
は外側の余白。内側の余白はipadx
/ipady
です(ボタンを大きく見せたい時などに有効)。
結果

例4: stickyでセル内の配置を制御(N/E/S/W)
import tkinter as tk
root = tk.Tk()
root.title("sticky")
tk.Label(root, text="Left").grid(row=0, column=0, sticky="w")
tk.Label(root, text="Right").grid(row=1, column=0, sticky="e")
root.mainloop()
解説:sticky
は方位で指定。"n" "e" "s" "w"
を組み合わせます(例:"ns"
で上下いっぱい、"nsew"
で全方向いっぱい)。
結果

sticky早見表(覚えると超ラク)
指定 | 意味 | よくある用途 |
---|---|---|
"" (未指定) | セル中央 | デフォルト |
"w" / "e" / "n" / "s" | 左 / 右 / 上 / 下に寄せる | ラベルを左寄せ、ボタンを右寄せ |
"we" | 左右いっぱい(横に伸ばす) | 入力欄やリストを横に広げたい |
"ns" | 上下いっぱい(縦に伸ばす) | フレームやリストの縦伸び |
"nsew" | 四方いっぱい(縦横に伸ばす) | メイン領域を可変にしたい時 |
文字列の代わりに tk.N|tk.S|tk.E|tk.W
とビットORで書くこともできます。
例5: リサイズ対応(rowconfigure/columnconfigure と weight)
import tkinter as tk
root = tk.Tk()
root.title("リサイズ対応")
tk.Label(root, text="Label 1", bg="#e3f2fd").grid(row=0, column=0, sticky="nsew")
tk.Label(root, text="Label 2", bg="#bbdefb").grid(row=1, column=0, sticky="nsew")
# 行・列の「伸び代」を設定
root.grid_rowconfigure(0, weight=1)
root.grid_rowconfigure(1, weight=1)
root.grid_columnconfigure(0, weight=1)
root.mainloop()
解説:weight
を与えた行/列がウィンドウ拡大時に伸びるようになります。sticky="nsew"
でセルいっぱいに広がります。
結果

実用テンプレ1:2カラム+リサイズ対応(フォーム用)
import tkinter as tk
root = tk.Tk()
root.title("2カラムフォーム")
frm = tk.Frame(root, padx=12, pady=12)
frm.grid(sticky="nsew")
# ウィンドウ&フレームの伸び設定
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
frm.grid_columnconfigure(0, weight=0, minsize=120) # ラベル列
frm.grid_columnconfigure(1, weight=1) # 入力列(横に伸びる)
# 行を作成
labels = ["お名前", "メール", "パスワード"]
entries = []
for i, text in enumerate(labels):
tk.Label(frm, text=text, anchor="w").grid(row=i, column=0, sticky="w", pady=6)
e = tk.Entry(frm)
e.grid(row=i, column=1, sticky="we", padx=(8, 0), pady=6)
entries.append(e)
# ボタン行(2列にまたがる)
btn = tk.Button(frm, text="送信")
btn.grid(row=len(labels), column=0, columnspan=2, sticky="e", pady=(12,0))
root.mainloop()
解説:
親→子の順にweightを設定、入力列はsticky="we"
で横に伸ばします。
結果

実用テンプレ2:サイドバー+メイン(2分割レイアウト)
import tkinter as tk
root = tk.Tk()
root.title("サイドバー+メイン")
# 2列構成
root.grid_columnconfigure(0, weight=0, minsize=180) # サイドバー固定幅
root.grid_columnconfigure(1, weight=1) # メインは伸びる
root.grid_rowconfigure(0, weight=1) # 縦も伸びる
sidebar = tk.Frame(root, bg="#f5f5f5")
main = tk.Frame(root, bg="#ffffff")
sidebar.grid(row=0, column=0, sticky="nsew")
main.grid(row=0, column=1, sticky="nsew")
# サイドバー中身(縦方向に詰める)
for i in range(5):
tk.Button(sidebar, text=f"Menu {i+1}", anchor="w").grid(row=i, column=0, sticky="we", padx=8, pady=6)
sidebar.grid_rowconfigure(5, weight=1) # 下の余白に押しやる
# メインは上部にヘッダ、下にリスト(縦横に伸ばす)
tk.Label(main, text="タイトル", font=("TkDefaultFont", 14, "bold")).grid(row=0, column=0, sticky="w", padx=12, pady=12)
listbox = tk.Listbox(main)
listbox.grid(row=1, column=0, sticky="nsew", padx=12, pady=(0,12))
main.grid_rowconfigure(1, weight=1)
main.grid_columnconfigure(0, weight=1)
root.mainloop()
grid
とpack
/place
の違い(選び方)
- grid:フォームや表形式、可変レイアウトに最適。最も汎用。
- pack:上下/左右に詰める感じ。簡単だが細かい制御が苦手。
- place:座標指定(ピクセルや相対)。ピンポイントだがリサイズに弱い。
結果

まとめ
grid
は(row, column)に置くのが基本sticky
で寄せ方/伸ばし方、padx/pady
で余白を調整rowconfigure/columnconfigure
+weight
でリサイズ対応- 混在注意:同じ親で
grid
とpack
は使わない - 実務はFrameを分けて小さなグリッドを組み合わせるのがコツ