tkinterではwidget(例:Frame、Canvas)を配置するには3つの方法 grid, pack, placeがあります。
今回はgridに焦点を当ててwidgetの配置方法についてまとめていきます。
前準備
grid()
の使い方について見る前に、template.py
とapp.py
を用意します。この2つのプログラムを使ってgrid()
の使い方について見ていきます。
template.py
import tkinter as tk
from PIL import ImageTk
class Template(tk.Tk):
def __init__(self, **kwargs):
super(Template, self).__init__()
self.title(kwargs.get("title", "tkinter"))
self.geometry("+{}+{}".format(*kwargs.get("pos", (0, 0))))
self.resizable(*kwargs.get("resize", (1, 1)))
try:
self.iconbitmap(kwargs.get("icon", None))
except:
if kwargs.get("icon", None) is not None:
icon_name = kwargs.get("icon")
icon_img = ImageTk.PhotoImage(file=icon_name)
self.tk.call("wm", "iconphoto", self._w, icon_img)
def run(self):
self.mainloop()
template.py
はアプリケーションの雛形として用意しました。ここでは、アプリケーションのタイトル、起動時のアプリケーションの位置、アプリケーションの拡大拡小の設定、アプリケーションのアイコンについて設定をすることができます。設定はtemplate.py
を継承したクラスでするようにしてあります。
関連記事 - はじめてのtkinter ウィンドウを作って表示させる
app.py
import tkinter as tk
from template import Template
class App(Template):
def __init__(self):
super(App, self).__init__()
self.createWidgets()
self.attachWidgets()
def createWidgets(self):
pass
def attachWidgets(self):
pass
if __name__ == "__main__":
app = App()
app.run()
template.py
のTemplateクラスを継承しています。今回は特にアプリケーションのタイトル、位置、拡大拡小、アイコンの設定については行いません。createWidgets
でWidgetの作成、attachWidgets()
で作成したWidgetをウィンドウに配置していきます。
gridの使い方
今回、grid()
の使い方を見るにあたり3つのFrame、frame_1
、frame_2
、frame_3
を用意しました。
def createWidgets(self):
self.frame_1 = tk.Frame(self, width=100, height=100, bg="coral")
self.frame_2 = tk.Frame(self, width=100, height=100, bg="tan")
self.frame_3 = tk.Frame(self, width=100, height=100, bg="violet")
def attachWidgets(self):
self.frame_1.grid()
self.frame_2.grid()
self.frame_3.grid()
それぞれgrid()
を使ってウィンドウに配置し、プログラムを実行すると
$ python app.py
下のウィンドウが起動します。

row, rowspan(行についての設定)
row
はwidgetを何行目に配置するかを設定します。
rowspan
はデフォルトで1になっていて、指定した場合(2以上)、複数の行にまたがってwidgetが配置されます。

上のように3つのFrameを3行にわたって配置するには、
def attachWidgets(self):
self.frame_1.grid(row=0)
self.frame_2.grid(row=1)
self.frame_3.grid(row=2)

また、rowspan
を3にしたときにFrameを3行にわたって配置するには以下のようにします。
def attachWidgets(self):
self.frame_1.grid(rowspan=3, row=0)
self.frame_2.grid(row=3)
self.frame_3.grid(row=6)
rowspan
を3に設定しているので、3行にまたがってwidgetが配置されるようになっています。したがって、frame_2
とframe_3
のrow
をそれぞれ3と6に設定しています。

column, columnspan(列についての設定)
column
はwidgetを何列目に配置するかを設定します。
columnspan
はデフォルトで1になっていて、指定した場合(2以上)、複数の列にまたがってwidgetが配置されます。

上のように3つのFrameを3列にわたって配置するには、
def attachWidgets(self):
self.frame_1.grid(column=0, row=0)
self.frame_2.grid(column=1, row=0)
self.frame_3.grid(column=2, row=0)
また、columnspan
を2にしたときにFrameを3列にわたって配置するには以下のようにします。
def attachWidgets(self):
self.frame_1.grid(columnspan=2, column=0, row=0)
self.frame_2.grid(column=2, row=0)
self.frame_3.grid(column=4, row=0)
columnspan
を2に設定しているので、2列にまたがってwidgetが配置されるようになっています。したがって、frame_2
とframe_3
をそれぞれ2と4に設定しています。

sticky
はwidgetの配置位置と拡大方向の設定をすることができます。
指定できる定数はS
、N
、E
、W
、NW
、NE
、SW
、SE
があり、例えばsticky=tk.W
とすると、widgetを左に寄せて配置し、sticky=tk.W+tk.S
とすると、widgetを左右に引き伸ばして配置します。さらに、sticky=tk.W+tk.E+tk.N+tk.S
とすると、widgetを全方向に引き伸ばして配置します。
つまり、+がなければ配置位置の設定、+があればwidgetを引き伸ばす方向の設定をすることができます。
ipadx, ipady(内側のpadding)
ipadx
とipady
はそれぞれwidgetの内側の高さと横の長さを設定することができます。デフォルトでは0になっています。
padx, pady(外側のpadding)
padx
とpady
はそれぞれwidgetの外側の高さと横の長さを設定することができます。デフォルトでは0になっています。
createWidgets()
とattachWidgets()
を以下のようにして、paddingの使い方について見ていきます。
def createWidgets(self):
self.frame_1 = tk.Frame(self, width=100, height=100, bg="coral")
self.canvas_red = tk.Canvas(self.frame_1, width=30, height=30, bg="red")
self.canvas_blue = tk.Canvas(self.frame_1, width=30, height=30, bg="blue")
def attachWidgets(self):
self.frame_1.grid()
self.canvas_red.grid(column=0, row=0)
self.canvas_blue.grid(column=0, row=1)
このコードを実行すると、下のウィンドウが起動します。

ipadx
とipady
をそれぞれ10にして、
def attachWidgets(self):
self.frame_1.grid()
self.canvas_red.grid(column=0, row=0, ipadx=10, ipady=10)
self.canvas_blue.grid(column=0, row=1)
このコードを実行すると、下のウィンドウが起動します。

padx
とpady
をそれぞれ10にして、
def attachWidgets(self):
self.frame_1.grid()
self.canvas_red.grid(column=0, row=0, padx=10, pady=10)
self.canvas_blue.grid(column=0, row=1)
このコードを実行すると、下のウィンドウが起動します。

padx
とpady
はipadx
とipady
と違って、もう少し細かく設定をすることができます。
例えば、padx
とpady
を以下のようにして
def attachWidgets(self):
self.frame_1.grid()
self.canvas_red.grid(column=0, row=0, padx=(30, 5), pady=(0, 10))
self.canvas_blue.grid(column=0, row=1)
このコードを実行すると、下のウィンドウが起動します。

padx
とpady
はそれぞれpadx=(左、右)
、pady=(上、下)
と細かく設定をすることができます。
サンプルコード
3つのフレームを使ってレイアウト構成のサンプルを見ていきます。
def createWidgets(self):
self.frame_1 = tk.Frame(self, width=100, height=100, bg="coral")
self.frame_2 = tk.Frame(self, width=100, height=100, bg="tan")
self.frame_3 = tk.Frame(self, width=100, height=100, bg="violet")
frame_1
を左側、frame_2
とframe_3
を右側に上から順に配置する。

このレイアウトにするにはgrid()
の設定を以下のようにする。
def attachWidgets(self):
self.frame_1.grid(rowspan=2, column=0, row=0)
self.frame_2.grid(column=1, row=0)
self.frame_3.grid(column=1, row=1)
ただ、これだとframe_1
の上下に隙間ができてしまうので、
下のようにするには

frame_1
の上下の隙間を埋めるにはsticky
の設定をtk.N+tk.S
とすることで、frame_1
を上下に引き伸ばすことができます。
def attachWidgets(self):
self.frame_1.grid(
rowspan=2,
column=0, row=0, sticky=tk.N+tk.S
)
self.frame_2.grid(column=1, row=0)
self.frame_3.grid(column=1, row=1)
frame_1
を上側、frame_2
とframe_3
を下側に左から順に配置する。

frame_1
の左右の隙間を埋めるためにsticky
の設定をtk.W+tk.E
としています。
def attachWidgets(self):
self.frame_1.grid(
columnspan=2,
column=0, row=0,
sticky=tk.W+tk.E
)
self.frame_2.grid(column=0, row=1)
self.frame_3.grid(column=1, row=1)
frame_1
を下側、frame_2
とframe_3
を上側に左から順に配置する。

frame_1
の左右の隙間を埋めるためにsticky
の設定をtk.W+tk.E
としています。
def attachWidgets(self):
self.frame_1.grid(
columnspan=2,
column=0, row=1,
sticky=tk.W+tk.E
)
self.frame_2.grid(column=0, row=0)
self.frame_3.grid(column=1, row=0)
frame_1
を右側、frame_2
とframe_3
を左側に上から順に配置する。

frame_1
の上下の隙間を埋めるためにsticky
の設定をtk.S+tk.N
としています。
def attachWidgets(self):
self.frame_1.grid(
rowspan=2,
column=1, row=0,
sticky=tk.S+tk.N
)
self.frame_2.grid(column=0, row=0)
self.frame_3.grid(column=0, row=1)
frame_1
を左上、frame_2
を右上、frame_3
を左下、frame_4
を右下に配置する。

def createWidgets(self):
self.frame_1 = tk.Frame(self, width=100, height=100, bg="coral")
self.frame_2 = tk.Frame(self, width=100, height=100, bg="tan")
self.frame_3 = tk.Frame(self, width=100, height=100, bg="violet")
self.frame_4 = tk.Frame(self, width=100, height=100, bg="cyan")
def attachWidgets(self):
self.frame_1.grid(column=0, row=0)
self.frame_2.grid(column=1, row=0)
self.frame_3.grid(column=0, row=1)
self.frame_4.grid(column=1, row=1)
おわり
grid
の使い方について紹介しました。
tkinterについて他にもいろいろ書いているので、ご興味があるかたはぜひ以下の記事を見てみてください。
www.pytry3g.com
参考記事 - The Tkinter Grid Geometry Manager