英文:
Tkinter Radiobuttons not working properly in Toplevel window
问题
I'm building a GUI with Tkinter in Python and I'm having trouble with radio buttons. I have two radio buttons in a LabelFrame widget and I'm using a StringVar to track the selected value. However, when I run the program, both radio buttons are initially unselected, but after a few seconds both become selected. Additionally, changes to the selected value are not always reflected in the GUI.
Here is my code:
import tkinter as tk
class MenuSettings:
def __init__(self, parent, settings):
window = tk.Toplevel(parent)
window.title("settings")
database_frame = tk.LabelFrame(
window, text="choose drive: ", font=("Arial", 12))
database_frame.pack(fill=tk.X, padx=10, pady=10)
database_var = tk.StringVar(value=settings.db_path)
database_radio_g = tk.Radiobutton(
database_frame, text="G:", value="PATH_G", variable=database_var,
font=("Arial", 12))
database_radio_g.pack(side="left", padx=10)
database_radio_server = tk.Radiobutton(
database_frame, text="Server", value="PATH_SERVER", variable=database_var,
font=("Arial", 12))
database_radio_server.pack(side="left", padx=10)
#-----------------------------------------------------------------------
# The following code is necessary:
#-----------------------------------------------------------------------
#def on_database_var_changed(*args):
# print('database_var changed:', database_var.get())
#database_var.trace('w', on_database_var_changed)
from wotan.CLS import cls
settings = cls.Settings.getInstance()
class Application(tk.Tk):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.title("Application")
self.configure(background='black')
self._show_menu_settings()
def _show_menu_settings(self):
settings_window = MenuSettings(self, settings)
def main():
app = Application()
app.mainloop()
if __name__ == '__main__':
main()
settings
is a singleton class to read some variables from a locally stored textfile.
Trace statement incl. function is commented out in the MenuSettings
class.
I've tried several things, such as setting the value option for the radio buttons, removing other parts of my code to isolate the issue, use window.update()
and window.update_idletasks()
, but nothing seems to work.
The only solution I found is to add a trace with a function to print the StringVar, which is not an ideal solution for an App.
Does anyone have any suggestions for how to fix this issue?
英文:
I'm building a GUI with Tkinter in Python and I'm having trouble with radio buttons. I have two radio buttons in a LabelFrame widget and I'm using a StringVar to track the selected value. However, when I run the program, both radio buttons are initially unselected, but after a few seconds both become selected. Additionally, changes to the selected value are not always reflected in the GUI.
Here is my code:
import tkinter as tk
class MenuSettings:
def __init__(self, parent, settings):
window = tk.Toplevel(parent)
window.title("settings")
database_frame = tk.LabelFrame(
window, text="choose drive: ", font=("Arial", 12))
database_frame.pack(fill=tk.X, padx=10, pady=10)
database_var = tk.StringVar(value=settings.db_path)
database_radio_g = tk.Radiobutton(
database_frame, text="G:", value="PATH_G", variable=database_var,
font=("Arial", 12))
database_radio_g.pack(side="left", padx=10)
database_radio_server = tk.Radiobutton(
database_frame, text="Server", value="PATH_SERVER", variable=database_var,
font=("Arial", 12))
database_radio_server.pack(side="left", padx=10)
#-----------------------------------------------------------------------------
# following code is necessary
#-----------------------------------------------------------------------------
#def on_database_var_changed(*args):
# print('database_var changed:', database_var.get())
#database_var.trace('w', on_database_var_changed)
from wotan.CLS import cls
settings = cls.Settings.getInstance()
class Application(tk.Tk):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.title("Application")
self.configure(background='black')
self._show_menu_settings()
def _show_menu_settings(self):
settings_window=MenuSettings(self, settings)
def main():
app = Application()
app.mainloop()
if __name__ == '__main__':
main()
settings
is a singleton class to read some variables from a locally stored textfile.
Trace statement incl. function is commented out in class MenuSettings
I've tried several things, such as setting the value option for the radio buttons, removing other parts of my code to isolate the issue, use window.update() and window.update_idletasks(), but nothing seems to work.
The only solution I found is to add a trace with a function to print the StringVar, which is not an ideal solution for an App.
Does anyone have any suggestions for how to fix this issue?
答案1
得分: 2
You need to use instance variable on database_var
(in MenuSettings
) and settings_window
(in Application
) to avoid garbage collection:
class MenuSettings:
def __init__(self, parent, settings):
...
# 使用实例变量
self.database_var = tk.StringVar(value=settings.db_path)
database_radio_g = tk.Radiobutton(
database_frame, text="G:", value="PATH_G", variable=self.database_var,
font=("Arial", 12))
database_radio_g.pack(side="left", padx=10)
database_radio_server = tk.Radiobutton(
database_frame, text="Server", value="PATH_SERVER", variable=self.database_var,
font=("Arial", 12))
database_radio_server.pack(side="left", padx=10)
...
class Application(tk.Tk):
...
def _show_menu_settings(self):
# 使用实例变量
self.settings_window = MenuSettings(self, settings)
...
I would suggest that MenuSettings
inherits from tk.Toplevel
, then you don't need to use an instance variable on settings_window
.
英文:
You need to use instance variable on database_var
(in MenuSettings
) and settings_window
(in Application
) to avoid garbage collection:
class MenuSettings:
def __init__(self, parent, settings):
...
# use instance variable
self.database_var = tk.StringVar(value=settings.db_path)
database_radio_g = tk.Radiobutton(
database_frame, text="G:", value="PATH_G", variable=self.database_var,
font=("Arial", 12))
database_radio_g.pack(side="left", padx=10)
database_radio_server = tk.Radiobutton(
database_frame, text="Server", value="PATH_SERVER", variable=self.database_var,
font=("Arial", 12))
database_radio_server.pack(side="left", padx=10)
...
class Application(tk.Tk):
...
def _show_menu_settings(self):
# use instance variable
self.settings_window = MenuSettings(self, settings)
...
I would suggest that MenuSettings
inherits form tk.Toplevel
instead, then you don't need to use instance variable on settings_window
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论