質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Q&A

解決済

1回答

394閲覧

コンボボックスでウィジェットを切り替える際の挙動がおかしい

nkfrom_asu

総合スコア10

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

0グッド

0クリップ

投稿2022/12/18 13:55

編集2022/12/19 13:38

前提

コンボボックスでウィジェットを切り替えるプログラムを作成しています。
"False" は非表示、"True"FrameColor というフレームを表示するようにしています。

発生している問題

45行目の user_interface.create_nest_widget()__init__ 内に移動したいのですが、フレームの中身が表示されません。2回目以降は self.propagate(False) が効いてない状態で表示されます。
(元のコードでは2回目以降でも表示されませんが…)

また、45行目にあっても、2回以上 "True" を選択すると self.propagate(False) が外れてしまいます。(元のコードでは外れていないので、どこか必要な部分を省いてしまったのかもしれません。)

よろしくお願いいたします。

Python

1import tkinter as tk 2from tkinter import ttk 3 4class UserInterface(tk.Frame): 5 def __init__(self, master): 6 super().__init__(master) 7 self.var_combobox = tk.StringVar() 8 combobox = ttk.Combobox( 9 self, textvariable=self.var_combobox, 10 values=("False", "True"), width=30 11 ) 12 combobox.current(0) 13 combobox.bind("<<ComboboxSelected>>", self.change_widget) 14 combobox.grid() 15 # self.create_nest_widget() 16 17 def create_nest_widget(self): 18 self.update() #「user_interface」の幅を取得 19 self.label_color = FrameColor(self, self.winfo_width()) 20 21 def change_widget(self, event): 22 self.label_color.grid_forget() 23 if self.var_combobox.get() == "False": 24 return 25 self.label_color.grid(sticky=tk.W) 26 27class FrameColor(tk.Frame): 28 def __init__(self, master, user_interface_width): 29 super().__init__(master) 30 self.config(width=user_interface_width//2, height=44, bg="blue") 31 self.grid_propagate(False) 32 33 label = tk.Label(self, text="Pick a color") 34 label.grid(row=0, padx=2) 35 36 image = tk.PhotoImage(data="", width=12, height=12) 37 self.button = tk.Button(self, image=image, bg="red") 38 self.button.grid(row=1, sticky=tk.W, padx=5) 39 40class App(tk.Tk): 41 def __init__(self): 42 super().__init__() 43 user_interface = UserInterface(self) 44 user_interface.pack() 45 user_interface.create_nest_widget() 46 47 48def main(): 49 app = App() 50 app.mainloop() 51 52if __name__ == "__main__": 53 main() 54

元のコードと同じ挙動をする省略版です。FrameColor まわりを省略しすぎていたようです。

Python

1import tkinter as tk 2from tkinter import ttk 3 4class UserInterface(tk.Frame): 5 def __init__(self, master): 6 super().__init__(master) 7 self.var_combobox = tk.StringVar() 8 combobox = ttk.Combobox( 9 self, textvariable=self.var_combobox, 10 values=("False", "True"), width=30 11 ) 12 combobox.current(0) 13 combobox.bind("<<ComboboxSelected>>", self.change_widget) 14 combobox.grid() 15 self.create_nest_widget() 16 17 def create_nest_widget(self): 18 self.update() #「user_interface」の幅を取得 19 self.frame_color = FrameColor(self, self.winfo_width()) 20 21 def change_widget(self, event): 22 self.frame_color.grid_remove() 23 if self.var_combobox.get() == "False": 24 return 25 self.frame_color.grid(sticky=tk.W) 26 27class FrameColor(tk.Frame): 28 def __init__(self, master, user_interface_width): 29 super().__init__(master) 30 left_label_color = LabelColor(self, user_interface_width) 31 left_label_color.grid(row=1, column=0) 32 33class LabelColor(tk.Frame): 34 def __init__(self, master, user_interface_width): 35 super().__init__(master) 36 self.config(width=user_interface_width//2, height=44, bg="blue") 37 self.grid_propagate(False) 38 39 label = tk.Label(self, text="Pick a color") 40 label.grid(row=0, padx=2) 41 42 image = tk.PhotoImage(data="", width=12, height=12) 43 self.button = tk.Button(self, image=image, bg="red") 44 self.button.grid(row=1, sticky=tk.W, padx=5) 45 46class App(tk.Tk): 47 def __init__(self): 48 super().__init__() 49 user_interface = UserInterface(self) 50 user_interface.pack() 51 # user_interface.create_nest_widget() 52 53 54def main(): 55 app = App() 56 app.mainloop() 57 58if __name__ == "__main__": 59 main() 60

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

grid_forget だと、オプションもリセットされるので
その都度、呼び出し側での再設定が必要です。

grid_forget の代わりに grid_remove にすれば、オプション類が保持されるので
2回目以降も .grid() と、オプションなしの呼び出しのみで以前た同じ表示状態に戻ります。

投稿2022/12/19 04:50

teamikl

総合スコア8664

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nkfrom_asu

2022/12/19 11:50

回答ありがとうございます。 その問題に関しては、元のコードと同じようにクラス内に収めることで解決しました。 一つ目の問題に関してはいまだ解決していません。
teamikl

2022/12/19 14:20

2つめのコードでは正しい width が得らてれません。 (user_interface.pack() での配置より前に Frame の width を得ようとしている) Frame ではなく、combobox の winfo_reqwidth() を渡すようにしてみてください。
nkfrom_asu

2022/12/21 13:10

winfo_reqwidthで解決しました!comboboxでなくても取得できました。 comboboxならwinfo_widthのままでも取得できますね。 winfo_reqwidthが一番手軽なので、これでいきたいと思います。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問