Tkinterのレイアウト方法は3種類

 今日も見に来てくださってありがとうございます。着々と読者が増えているようでうれしいです。がんばって書いていきます。

 ここのところtkinterで遊んでいます。tkinterではウィジェットと呼ばれる部品が用意されているのですが、それをウィンドウ内の適切な位置に配置する必要があります。tkinterではその配置する方法が、pack、grid、placeの3種類あります。全部使ってみました、という例を作ってみました。ちなみにこれらは、ジオメトリマネージャ(geometry manager)と呼ばれています。配置を管理するための仕組みですね。これらが組み合わせられるか、お試しでプログラムを作ってみました。

ソースコードは、以下の通りです。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import tkinter as tk
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("geometry manager test")
gridframe = tk.LabelFrame(self, text="グリッドのフレーム")
gridframe.pack()
g = GridFrame(gridframe)
g.pack()
packframe = tk.LabelFrame(self, text="パックのフレーム")
packframe.pack()
pa = PackFrame(packframe)
pa.pack()
placeframe = tk.LabelFrame(self, text="プレースのフレーム")
placeframe.pack(ipadx=10, ipady=5, expand=True, fill=tk.BOTH)
pl = PlaceFrame(placeframe)
pl.pack()
label = tk.Label(text="ラベル")
button = tk.Button(text="ボタン",command=self.destroy)
label.pack()
button.pack()
class GridFrame(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
label = tk.Label(self,text="gridのラベル")
label.grid(column=0,row=0,padx=10,pady=10)
button = tk.Button(self,text="gridのボタン")
button.grid(column=1,row=1,padx=10,pady=10)
class PackFrame(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
label = tk.Label(self, text="packのラベル")
button = tk.Button(self, text="packのボタン")
label.pack(padx=20,pady=20)
button.pack(padx=20,pady=20)
class PlaceFrame(tk.Frame):
def __init__(self, master=None):
super().__init__(master,width=300,height=50)
label = tk.Label(self, text="placeのラベル")
button = tk.Button(self, text="placeのボタン")
label.place(relwidth=0.25, relheight=0.25)
button.place(anchor=tk.N, x=200, y=20, width=80, height=30)
if __name__ == "__main__":
app = App()
app.mainloop()
import tkinter as tk class App(tk.Tk): def __init__(self): super().__init__() self.title("geometry manager test") gridframe = tk.LabelFrame(self, text="グリッドのフレーム") gridframe.pack() g = GridFrame(gridframe) g.pack() packframe = tk.LabelFrame(self, text="パックのフレーム") packframe.pack() pa = PackFrame(packframe) pa.pack() placeframe = tk.LabelFrame(self, text="プレースのフレーム") placeframe.pack(ipadx=10, ipady=5, expand=True, fill=tk.BOTH) pl = PlaceFrame(placeframe) pl.pack() label = tk.Label(text="ラベル") button = tk.Button(text="ボタン",command=self.destroy) label.pack() button.pack() class GridFrame(tk.Frame): def __init__(self, master=None): super().__init__(master) label = tk.Label(self,text="gridのラベル") label.grid(column=0,row=0,padx=10,pady=10) button = tk.Button(self,text="gridのボタン") button.grid(column=1,row=1,padx=10,pady=10) class PackFrame(tk.Frame): def __init__(self, master=None): super().__init__(master) label = tk.Label(self, text="packのラベル") button = tk.Button(self, text="packのボタン") label.pack(padx=20,pady=20) button.pack(padx=20,pady=20) class PlaceFrame(tk.Frame): def __init__(self, master=None): super().__init__(master,width=300,height=50) label = tk.Label(self, text="placeのラベル") button = tk.Button(self, text="placeのボタン") label.place(relwidth=0.25, relheight=0.25) button.place(anchor=tk.N, x=200, y=20, width=80, height=30) if __name__ == "__main__": app = App() app.mainloop()
import tkinter as tk

class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("geometry manager test")

        gridframe = tk.LabelFrame(self, text="グリッドのフレーム")
        gridframe.pack()
        g = GridFrame(gridframe)
        g.pack()
        
        packframe = tk.LabelFrame(self, text="パックのフレーム")
        packframe.pack()
        pa = PackFrame(packframe)
        pa.pack()

        placeframe = tk.LabelFrame(self, text="プレースのフレーム")
        placeframe.pack(ipadx=10, ipady=5, expand=True, fill=tk.BOTH)
        pl = PlaceFrame(placeframe)
        pl.pack()

        label = tk.Label(text="ラベル")
        button = tk.Button(text="ボタン",command=self.destroy)
        label.pack()
        button.pack()

class GridFrame(tk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        label = tk.Label(self,text="gridのラベル")
        label.grid(column=0,row=0,padx=10,pady=10)
        button = tk.Button(self,text="gridのボタン")
        button.grid(column=1,row=1,padx=10,pady=10)

class PackFrame(tk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        label = tk.Label(self, text="packのラベル")
        button = tk.Button(self, text="packのボタン")
        label.pack(padx=20,pady=20)
        button.pack(padx=20,pady=20)
        
class PlaceFrame(tk.Frame):
    def __init__(self, master=None):
        super().__init__(master,width=300,height=50)
        label = tk.Label(self, text="placeのラベル")
        button = tk.Button(self, text="placeのボタン")
        label.place(relwidth=0.25, relheight=0.25)
        button.place(anchor=tk.N, x=200, y=20, width=80, height=30)

if __name__ == "__main__":
    app = App()
    app.mainloop()

gridは格子状に分けた場所に部品を配置するイメージです。行と列で位置を指定することができます。また、columnspanrowspanを指定することで幅や高さを増やすことができます。packは真空パックのイメージでしょうか。部品をつくって、詰める感じです。placeは位置や大きさを直接指定するイメージですね。それぞれの詳細はまたいずれどこかでまとめようと思います。

ひとつのコンテナの中で異なる方法を混ぜて使うことはできません。エラーが発生して処理が中断してしまいます。今回のこの例のようにFrameを継承したコンテナの中に部品を配置して、それらを組み合わせる、というのがコツのようです。こうすることで、それぞれが独立して影響を及ぼさないようにつくることができます。

たったこれだけの部品を並べるのに、こんなに書かないといけないのは、けっこう面倒ですよね。でもまあ、つくって、並べて、つくって、並べて、と、これより短くするのはかなり難しい(ムリ)でしょうね。

コメントを残す

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


reCaptcha の認証期間が終了しました。ページを再読み込みしてください。