Python tkinterのウィジットの配置でハマった話


はじめに

・Pythonでデスクトップアプリを開発する際に、tkinterライブラリを使用すると思います。

・ウィジットの配置にはpack,grid,placeがありますが、今回は細かいレイアウト調整が可能なplaceを使用しました。

・しかし、ウィジットが思い通りに配置できなかったのでメモを残します。

やりたいこと

・Frameを入れ子して、親フレームの相対位置に子フレームを配置したい。

NGコード

test.py
import tkinter as tk

class Main(tk.Frame):

    def __init__(self, master=None):
        super().__init__(master)
        self.master.geometry("1000x1000") 
        self.master.title("サンプル")
        self.create_widgets()

    def create_widgets(self):
        self.frame1 = tk.Frame(self.master, height=500, width=500, bg="red").place(x=50,y=50)
        self.frame2 = tk.Frame(self.frame1, height=300, width=300, bg="green").place(x=50,y=50)
        self.frame3 = tk.Frame(self.frame2, height=100, width=100, bg="blue").place(x=50,y=50)

app = Main()
app.pack()
app.mainloop()


・NGコード実行結果

・全フレームが絶対位置(50,50)の位置に配置されてしまった。

修正コード

test.py
import tkinter as tk

class Main(tk.Frame):

    def __init__(self, master=None):
        super().__init__(master)
        self.master.geometry("1000x1000") 
        self.master.title("サンプル")
        self.create_widgets()

    def create_widgets(self):
        self.frame1 = tk.Frame(self.master, height=500, width=500, bg="red")
        self.frame1.place(x=50,y=50)
        self.frame2 = tk.Frame(self.frame1, height=300, width=300, bg="green")
        self.frame2.place(x=50,y=50)
        self.frame3 = tk.Frame(self.frame2, height=100, width=100, bg="blue")
        self.frame3.place(x=50,y=50)

app = Main()
app.pack()
app.mainloop()

修正コードの実行結果

・親フレームの相対位置(50,50)に子フレームを配置できた。

修正したところ

test.py
#一行のコードでウィジットの作成と配置
#self.frame1 = tk.Frame(self.master, height=500, width=500, bg="red").place(x=50,y=50)
#ウィジットの作成と配置を分けて記載
self.frame1 = tk.Frame(self.master, height=500, width=500, bg="red")
self.frame1.place(x=50,y=50)

まとめ

どういうわけか詳細は不明ですが
・tkiterのレイアウトで(pack,grid,place)を使う際は、ウィジットの作成と描画コードを分けて書く。
・1行でまとめて書くと描画はされるが、レイアウトが上手くいかない。