はじめに
tkinterを使用して簡易的なアプリケーションを作成しており,FrameやWidgetを配置するpack()
や grid()
で詰まった点を紹介します.備忘録です.
問題点
表題の通り,フレーム内にgrid()
でウィジェットを配置しようとすると,親フレームがリサイズされてしまう現象が発生した.
下図(サンプル)のように配置したかった...
動作環境
- Python 3.12.0
- tkinter 8.6.12
やったこと
tkinterの配置メソッドはpack()
,grid()
,place()
があり,
-
pack()
... 縦・横並びに配置 -
grid()
... 格子状に配置 -
place()
... 指定座標にピンポイントで配置
という特徴があります.
今回のケースでは格子状に配置するのでgrid()
を採用しました.以下ソースコードです.
ソースコード
import tkinter as tk
root = tk.Tk()
root.title("tkinter")
frame = tk.Frame(root, width=1200, height=500, relief=tk.SOLID, bd=1)
frame.propagate(False)
frame.pack(side="left", fill=tk.Y, padx=2, pady=(0, 2))
inner_frame1 = tk.Frame(frame, width=200, height=100, relief=tk.SOLID, bd=1)
inner_frame1.grid(row=0, column=0, padx=5, pady=5, sticky=tk.NSEW)
inner_frame2 = tk.Frame(frame, width=200, height=100, relief=tk.SOLID, bd=1)
inner_frame2.grid(row=1, column=0, padx=5, pady=5, sticky=tk.NSEW)
inner_frame3 = tk.Frame(frame, width=200, height=100, relief=tk.SOLID, bd=1)
inner_frame3.grid(row=0, column=1, padx=5, pady=5, sticky=tk.NSEW)
inner_frame4 = tk.Frame(frame, width=200, height=100, relief=tk.SOLID, bd=1)
inner_frame4.grid(row=1, column=1, padx=5, pady=5, sticky=tk.NSEW)
root.mainloop()
L7のframe.propagate(False)
で,フレーム内のウィジェットによらずフレームサイズが変更されないようになります.
上述のコードを実行すると下図のようにinner_frameのサイズに合わせて親フレームの横幅が変更されてしまいました.
解決策
解決方法としては,L7のコードを以下のように変更しました.
# 変更前
frame.propagate(False)
# 変更後
frame.grid_propagate(False)
.grid_propagate(False)
ですが,基本的に前述の.propagate(False)
のgrid版だと思ってください.pack版の.pack_propagate(False)
もあります.
inner_frameをpackで配置すると.propagate(False)
でも親フレームはリサイズされないみたいです.
(そもそも子のフレームサイズをピッタリ合わせてサイズ不変にしたら,こんなこと起きないんですけどね.)
おわりに
grid()
を使用する際は親オブジェクトのpropagate()
に注意する必要がありそうなことがわかった.