【Python/tkinter】ウィジェットの配置(grid)

ウィジェットを配置するには、pack,grid,placeの3つのメソッドがありますが、ここではgridについて説明します。

gridでウィジェットを配置するのは、どことなくエクセルのセルにウィジェットを配置するようなイメージに似ています。

こんなイメージ↓

ただし、gridでは行番号(row)、列番号(column)は0(ゼロ)から始まります。

また、エクセルにはセルを結合して中央揃えという機能がありますが、gridにも同様の機能があり、rowspancolumnspanを使ってセルを結合します。

最初のエクセルのイメージで配置したプログラムがこちら↓(ウィジェットの範囲が分かり易いように背景色をつけました)

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()

(実行画面)

【Python/tkinter】ウィジェットの配置(grid)」への4件のフィードバック

  1. 上記にある「ただし、gridでは行番号(row)、列番号(column)は0(ゼロ)から始まります。」という文章、正しくは「ただし、gridでは列番号(row)、行番号(column)は0(ゼロ)から始まります。」かと思うのですが、いかがでしょうか

  2. tkinterのウィジェットのは一方法が理解できず、いろいろなサイトを見てきましたが、グリッドで配置する方法を教えていただきとても助かりました。
    直感的に操作できるようになりそうです

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください