どうすれば正常に動きますか。
最初にちょっと脱線ですが「正常に動かない」と言いたくなる気持ち自分にもわかります。「なぜ自分が指定したとおりに配置しないんだtkinterよ...」と言いたくなりますね。しかし自分はGUIアプリ作成を通じて「GUIシステムはあくまで自分の指示通りに動いているだけで、原因のほぼ100%が自分の仕様把握不足や注意不足に起因する」ということを学びました。ここは冷静に「どういう具合にレイアウトされているか」を確認するのがよいと思います。
まず書いた通りに正常に動いていることを示します。
それを示すためにレイアウトが行われている様子をデバッグプリントしてみました。
python
1import tkinter as tk
2
3
4class App(tk.Frame):
5 def __init__(self, master=None):
6 tk.Frame.__init__(self, master)
7 dbg_conf(self)
8 b1 = tk.Button(text='ほげ', command=self.btn_event)
9 dbg_conf(b1)
10 b1.pack(anchor=tk.W)
11
12 def btn_event(self):
13 b2 = tk.Button(self, text='ぴよ')
14 dbg_conf(b2)
15 b2.pack(anchor=tk.W)
16
17
18def dbg_conf(w):
19 w.bind('<Configure>', on_conf)
20
21
22def on_conf(ev):
23 print(f"widget={ev.widget} width={ev.width} height={ev.height} x={ev.x} y={ev.y}")
24
25
26if __name__ == '__main__':
27 mm = App()
28 mm.pack()
29 mm.mainloop()
(自分はtkinterの別名をTk
じゃなくてtk
とする習慣なので回答のコードではそう変えさせていただきました。)
===>
# 初期レイアウト動作
widget=.!button width=31 height=26 x=0 y=0 <--(B1)
widget=.!app width=1 height=1 x=59 y=26 <--(A1)
# ボタンを押したときに起きるレイアウト動作
widget=.!app.!button width=1 height=1 x=0 y=0 <--(B2)
widget=.!app width=30 height=26 x=45 y=26 <--(A2)
widget=.!app.!button width=30 height=26 x=0 y=0 <--(B2)
(B1), (B2)のxに着目してください。いずれも親に対してx座標が0、すなわち最西端に配置されてます。これはanchor=tk.Wの仕様通りです。
期待通りでない原因(+α)
b2はAppフレームの子供となっています。Appフレームのpackには何も指定してないのでデフォルト動作として親(所謂rootウィンドウ)に対して水平方向中央に配置されます。またAppフレームの大きさはb2を配置するのに必要最小限の大きさになります。つまりb2自体はAppフレームの最西端に配置されるのですが、Appフレームの方がrootに対して中央に配置されているので結局b2はウィンドウの左端には配置されなくなります。
こちらは原因とはちょっと違いますが・・・
b1はroot直下に配置されてます。Appフレームのpackはb1より後なのでrootに対してb1, Appフレームの順に並びます。まずこの階層自体が意図通りではないと思います。本当は
tk.Button(text='ほげ', command=self.btn_event)
ではなく
tk.Button(self, text='ほげ', command=self.btn_event)
のつもりだったのではないでしょうか?
対処案
対処方法は一通りではありませんが、一例をあげると
(1) Appフレームはpack(fill=tk.BOTH)
で配置する
こうすればAppフレームがボタンの大きさではなくrootウィンドウの大きさに合わせて広がってくれます。
(2) b1もAppフレームの子供にする
(1)だけでも見た目は期待どおりになりますが気持ち悪いので・・・
Windows 10, CPython 3.7, Tcl/Tk 8.6
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2019/04/24 12:47