Tkinterには文字や画像、ボタン、バーなどのウィジェット(Widget)を配置するメソッドが3つ用意されています。この記事ではそれらのメソッドとオプション引数について解説します。
目次
packメソッドによるウィジェットの配置
まずは最も簡単なpackメソッドについてみていきましょう。
packメソッドはウィジェットを縦または横に1次元的に配列するためのメソッドで、次のオプションが用意されています。
属性 | 説明 | 値 |
---|---|---|
anchor | 配置可能なスペースに余裕がある場合、Widget をどこに配置するか指定します |
tk.CENTER(中央) tk.W(左寄せ) tk.E(右寄せ) tk.N(上寄せ) tk.S(下寄せ) tk.NW(左上) tk.SW(左下) tk.NE(右上) tk.SE(右下) |
expand | 親widget が大きくなったとき、大きくなるかどうかを指定します | 1(大きくなる) 0(サイズを保持) |
fill | widget が空いているスペースを埋めるかどうか指定します | none(元のサイズを保持) x(横に広がる) y(縦に広がる) both(縦横に広がる) |
padx | 外側の横の隙間を指定します | ピクセル単位で数値を指定 |
pady | 外側の縦の隙間を指定します | ピクセル単位で数値を指定 |
ipadx | 内側の横の隙間を指定します | ピクセル単位で数値を指定 |
ipady | 内側の縦の隙間を指定します | ピクセル単位で数値を指定 |
side | どの方向からつめていくかを指定します | top(上から) left(左から) right(右から) bottom(下から) |
例としてラベルウィジェットを3つ並べたフレームを用意しました。
import tkinter as tk # tk.Frameを継承したApplicationクラスを作成 class Application(tk.Frame): def __init__(self, master=None): # コンストラクタを定義 super().__init__(master) # 継承元クラス(tk.Frame)のコンストラクタを呼び出し # ウィンドウの設定 self.master.title("ウィンドウのタイトル") # 実行内容 self.pack() # フレームを配置 self.create_widget() # 下記で定義しているcreate_widgetメソッドを実行 #create_widgetメソッドを定義 def create_widget(self): # ラベル1を作成 label1 = tk.Label(self.master, text=u"これはラベル1です", bg="lightskyblue", relief=tk.RIDGE, bd=2) # 背景色,レリーフ,ボーダー幅を指定 label1.pack() # ラベル2を作成 label2 = tk.Label(self.master, text=u"ラベル2!", bg="khaki", relief=tk.RIDGE, bd=2) # 背景色,レリーフ,ボーダー幅を指定 label2.pack() # ラベル3を作成 label3 = tk.Label(self.master, text=u"これはラベル3ですよおおおおおおおおおおだ", bg="yellowgreen", relief=tk.RIDGE, bd=2) # 背景色,レリーフ,ボーダー幅を指定 label3.pack() if __name__ == "__main__": # このファイルが実行されている場合の処理 root = tk.Tk() # rootインスタンスを生成 app = Application(master=root) # Applicationクラスからappインスタンスを生成 app.mainloop() # appインスタンスのイベントハンドラを呼び出し
このコードを実行すると次のようなウィンドウが表示されます。
試しに先ほどのコードを変更し、各ウィジェットの横幅を広げたり、各ウィジェット間に隙間を作ったりしてみましょう。次のように記述します。
import tkinter as tk # tk.Frameを継承したApplicationクラスを作成 class Application(tk.Frame): def __init__(self, master=None): super().__init__(master) # ウィンドウの設定 self.master.title("ウィンドウのタイトル") # 実行内容 self.pack() self.create_widget() #create_widgetメソッドを定義 def create_widget(self): # ラベル1を作成 label1 = tk.Label(self.master, text=u"これはラベル1です", bg="lightskyblue", relief=tk.RIDGE, bd=2) label1.pack(padx=5, pady=5, fill=tk.X) # 横と縦に余白を指定し、ウィジェットを横いっぱいに広げる # ラベル2を作成 label2 = tk.Label(self.master, text=u"ラベル2!", bg="khaki", relief=tk.RIDGE, bd=2) label2.pack(padx=5, pady=5, fill=tk.X) # 横と縦に余白を指定し、ウィジェットを横いっぱいに広げる # ラベル3を作成 label3 = tk.Label(self.master, text=u"これはラベル3ですよおおおおおおおおおおだ", bg="yellowgreen", relief=tk.RIDGE, bd=2) label3.pack(padx=5, pady=5, fill=tk.X) # 横と縦に余白を指定し、ウィジェットを横いっぱいに広げる if __name__ == "__main__": root = tk.Tk() app = Application(master=root) app.mainloop()
各ウィジェットが縦横5ピクセルの余白を取り、フレームの横幅いっぱいに広がって表示されました。
gridメソッドによるウィジェットの配置
gridメソッドはウィジェットを2次元的に配置するためのメソッドです。次のオプションが使用できます。
属性 | 説明 | 値 |
---|---|---|
column | 配置する列 | 数値 |
columnspan | 合計何列かを指定します | 数値 |
padx | 外側の横の隙間を指定します | ピクセル単位で数値を指定 |
pady | 外側の縦の隙間を指定します | ピクセル単位で数値を指定 |
ipadx | 内側の横の隙間を指定します | ピクセル単位で数値を指定 |
ipady | 内側の縦の隙間を指定します | ピクセル単位で数値を指定 |
row | 配置する行を指定します | 数値 |
rowspan | 合計何行かを指定します | 数値 |
sticky | スペースに余裕がある場合、どこに配置するか、どのように引き伸ばすかを指定します。位置決めには値を単独で、引き伸ばす場合には1つ目の値のあとで + に続けて値を指定します。 |
tk.CENTER(中央) tk.W(左寄せ) tk.E(右寄せ) tk.N(上寄せ) tk.S(下寄せ) tk.NW(左上) tk.SW(左下) tk.NE(右上) tk.SE(右下) |
実際に先ほどの3つのラベルを上段に1つ、下段に2つの2段の格子状にに配置してみましょう。次のように記述します。
import tkinter as tk # tk.Frameを継承したApplicationクラスを作成 class Application(tk.Frame): def __init__(self, master=None): super().__init__(master) # ウィンドウの設定 self.master.title("ウィンドウのタイトル") # 実行内容 self.pack() self.create_widget() #create_widgetメソッドを定義 def create_widget(self): # ラベル1を作成 label1 = tk.Label(self, text=u"これはラベル1です", bg="lightskyblue", relief=tk.RIDGE, bd=2) label1.grid(row=0, column=0, columnspan=2, padx=5, pady=5) # 0行目の0列目に配置、横と縦に余白を指定 # ラベル2を作成 label2 = tk.Label(self, text=u"ラベル2!", bg="khaki", relief=tk.RIDGE, bd=2) label2.grid(row=1, column=0, padx=5, pady=5) # 1行目の0列目に配置、横と縦に余白を指定 # ラベル3を作成 label3 = tk.Label(self, text=u"これはラベル3ですよおおおおおおおおおおだ", bg="yellowgreen", relief=tk.RIDGE, bd=2) label3.grid(row=1, column=1, padx=5, pady=5) # 1行目の1列目に配置、横と縦に余白を指定 if __name__ == "__main__": root = tk.Tk() app = Application(master=root) app.mainloop()
上段、下段の2段に分かれ、2段目が2列に分かれた格子状にラベルを配置することができました。
ではまたコードを変更し、1列目のラベルを横幅いっぱいに広げてみましょう。次のように記述します。
import tkinter as tk # tk.Frameを継承したApplicationクラスを作成 class Application(tk.Frame): def __init__(self, master=None): super().__init__(master) # ウィンドウの設定 self.master.title("ウィンドウのタイトル") # 実行内容 self.pack() self.create_widget() #create_widgetメソッドを定義 def create_widget(self): # ラベル1を作成 label1 = tk.Label(self, text=u"これはラベル1です", bg="lightskyblue", relief=tk.RIDGE, bd=2) label1.grid(row=0, column=0, columnspan=2, padx=5, pady=5, sticky=tk.W+tk.E) # 0行目の0列目に配置、横と縦に余白を指定、ウィジェットを横いっぱいに広げる # ラベル2を作成 label2 = tk.Label(self, text=u"ラベル2!", bg="khaki", relief=tk.RIDGE, bd=2) # 背景色を指定 label2.grid(row=1, column=0, padx=5, pady=5) # 1行目の0列目に配置、横と縦に余白を指定 # ラベル3を作成 label3 = tk.Label(self, text=u"これはラベル3ですよおおおおおおおおおおだ", bg="yellowgreen", relief=tk.RIDGE, bd=2) # 背景色を指定 label3.grid(row=1, column=1, padx=5, pady=5) # 1行目の1列目に配置、横と縦に余白を指定 if __name__ == "__main__": root = tk.Tk() app = Application(master=root) app.mainloop()
1段目のラベルが横いっぱいに広がっているのがわかります。
placeメソッドによるウィジェットの配置
placeメソッドはウィジェットをピクセル指定で直接配置する方法です。 親ウィジェットに対する相対値で指定する方法と、絶対値で指定する方法があります。
place メソッドを使うときは親フレームの width と height をあらかじめ指定しておく必要があります。次のオプションが使用できます。
属性 | 説明 | 値 |
---|---|---|
anchor | 配置可能なスペースに余裕がある場合、Widget をどこに配置するか指定します |
tk.CENTER(中央) tk.W(左寄せ) tk.E(右寄せ) tk.N(上寄せ) tk.S(下寄せ) tk.NW(左上) tk.SW(左下) tk.NE(右上) tk.SE(右下) |
bordermode | 縁を内側、外側のどちらに付けるかを指定します | tk.INSIDE(内側) tk.OUTSIDE(外側) |
width | 幅を指定します | ピクセル単位で数値を指定 |
height | 高さを指定します | ピクセル単位で数値を指定 |
relheight | 親 widget に対する相対的な高さを指定 | 0.0~1.0の実数 |
relwidth | 親 widget に対する相対的な幅を指定 | 0.0~1.0の実数 |
relx | 親 widget に対する相対的な横の位置を指定 | 0.0~1.0の実数 |
rely | 親 widget に対する相対的な縦の位置を指定 | 0.0~1.0の実数 |
x | 横の位置を指定します | ピクセル単位で数値を指定 |
y | 縦の位置を指定します | ピクセル単位で数値を指定 |
また先ほどの3つのラベルを配置してみましょう。placeメソッドはウィジェットを斜めに配置したい時に便利です。
import tkinter as tk # tk.Frameを継承したApplicationクラスを作成 class Application(tk.Frame): def __init__(self, master=None): super().__init__(master, width=200, height=100) # フレームの幅、高さを指定 # ウィンドウの設定 self.master.title("ウィンドウのタイトル") # 実行内容 self.pack() self.create_widget() #create_widgetメソッドを定義 def create_widget(self): # ラベル1を作成 label1 = tk.Label(self.master, text=u"これはラベル1です", bg="lightskyblue", relief=tk.RIDGE, bd=2) label1.place(relx=0.05, rely=0.1) # 横0.05、縦0.1の位置に配置 # ラベル2を作成 label2 = tk.Label(self.master, text=u"これはラベル2です", bg="khaki", relief=tk.RIDGE, bd=2) label2.place(relx=0.25, rely=0.4) # 横0.25、縦0.4の位置に配置 # ラベル3を作成 label3 = tk.Label(self.master, text=u"これはラベル3です", bg="yellowgreen", relief=tk.RIDGE, bd=2) label3.place(relx=0.45, rely=0.7) # 横0.45、縦0.7の位置に配置 if __name__ == "__main__": root = tk.Tk() app = Application(master=root) app.mainloop()
1つ1つの手動で設定する必要はありますが、ウィジェットを自在に配置できます。