I have a settings page with lots of checkbuttons on it so I am trying to reduce the code but I am struggling when it comes to getting the checkbutton value to work so far I have:-
def _create_checkbox(self, label, index, state=0):
x = label.replace(" ", "-").lower()
self.settings_list[x] = state
ttk.Label(self.settings_frame, text=label).grid(
row=index, column=0)
ttk.Checkbutton(
self.settings_frame, variable=self.settings_list[x]
).grid(row=index, column=1)
the idea was to put the checkbutton names in a dict and then update the dict with the value but it is not working as planned, with my code all checkbutton values update as if they were one.
example list:
self.settings_list = {"force-gamemode": "0", "allow-cheats": "1"}
Edit to show minimal working example, I did originally try to use variables (IntVar) but it failed (I cant remember why) but that's why I then switched to a dict:-
import tkinter as tk
from tkinter import ttk
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("tkinter dynamic checkbox example")
self.geometry("700x450")
self.settings_list = {"force-gamemode": "0", "allow-cheats": "1"}
self.settings_frame = tk.Frame(self)
self.settings_frame.grid(row=0, column=0)
# create settings content
self._create_checkbox("Force Gamemode", 0, 0)
tk.Label(
self.settings_frame, text="Label to show content between checkboxes"
).grid(row=1, column=0)
self._create_checkbox("Allow Cheats", 2, 0)
tk.Button(
self.settings_frame,
text="Create Properties File",
command=self._create_properties,
).grid(row=3, column=0, sticky="ew")
def _create_checkbox(self, label, index, state=0):
x = label.replace(" ", "-").lower()
self.settings_list[x] = state
ttk.Label(self.settings_frame, text=label).grid(
row=index, column=0, padx=5, pady=5, sticky="w"
)
ttk.Checkbutton(self.settings_frame, variable=self.settings_list[x]).grid(
row=index, column=1, padx=5, pady=5, sticky="w"
)
def _create_properties(self):
print(self.settings_list["force-gamemode"])
print(self.settings_list["allow-cheats"])
if __name__ == "__main__":
app = App()
app.mainloop()
CodePudding user response:
Since you passed an integer 0 as the textvariable
option of those Checkbutton
widgets, an implicit IntVar
will be created with name "0" for them. Therefore they will be changed together because they share same tkinter variable.
You need to change
self.settings_list[x] = state
to
self.settings_list[x] = tk.IntVar(value=state)
inside _create_checkbox()
.
CodePudding user response:
In addition to acw1668's answer, to check the value
def _create_properties(self):
print(self.settings_list["force-gamemode"].get())
print(self.settings_list["allow-cheats"].get())
so your code is ...
import tkinter as tk
from tkinter import ttk
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("tkinter dynamic checkbox example")
self.geometry("700x450")
self.settings_list = {"force-gamemode": "0", "allow-cheats": "0"}
self.settings_frame = tk.Frame(self)
self.settings_frame.grid(row=0, column=0)
# create settings content
self._create_checkbox("Force Gamemode", 0, 0)
tk.Label(self.settings_frame, text="Label to show content between checkboxes"
).grid(row=1, column=0)
self._create_checkbox("Allow Cheats", 2, 0)
tk.Button(self.settings_frame, text="Create Properties File",
command=self._create_properties
).grid(row=3, column=0, sticky="ew")
def _create_checkbox(self, label, index, state=0):
x = label.replace(" ", "-").lower()
self.settings_list[x] = tk.IntVar(value=state)
ttk.Label(self.settings_frame, text=label
).grid(row=index, column=0, padx=5, pady=5, sticky="w")
ttk.Checkbutton(self.settings_frame, variable=self.settings_list[x]
).grid(row=index, column=1, padx=5, pady=5, sticky="w")
def _create_properties(self):
print(self.settings_list["force-gamemode"].get())
print(self.settings_list["allow-cheats"].get())
if __name__ == "__main__":
app = App()
app.mainloop()