I'm trying to pass the CTkSlider()
's real-time value from the top level to the main window via the seperate class Variables
. I couldn't figure out what causes this issue. I'm open to any suggestion. What is wrong with this code, do you guys think? Thank you.
import customtkinter
class ToplevelWindow(customtkinter.CTkToplevel):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.variables = Variables()
self.slider = customtkinter.CTkSlider(self, height=29, from_=0, to=100, number_of_steps=10, progress_color="#19A7CE", button_color="#FB2576", command=self.get_value)
self.slider.grid()
def get_value(self, value):
self.variables.variables_variable = value
self.variables.update_value()
class App(customtkinter.CTk):
def __init__(self):
super().__init__()
self.toplevel_window : customtkinter.CTkToplevel = None
self.app_variable : int = 9
self.app_variable_1 : tuple = None
self.app_variable_2 : float = 1.5
self.app_condition : float = 0.5
self.button = customtkinter.CTkButton(master=self, command=self.open_toplevel)
self.button.grid()
def open_toplevel(self):
if self.toplevel_window is None or not self.toplevel_window.winfo_exists():
self.toplevel_window = ToplevelWindow(self)
else:
self.toplevel_window.focus()
def value_setter(self, size=50):
if self.app_condition < 1:
self.app_variable_1 = (size, size * self.app_variable_2)
else:
self.app_variable_1 = (size * self.app_variable_2, size)
def update_app_variable(self, size=50):
self.value_setter(size)
class Variables(App):
def __init__(self, *args, **kwargs):
self.variables_variable : int
def update_value(self):
super().update_app_variable(self.variables_variable)
if __name__ == "__main__":
app = App()
app.mainloop()
Traceback:
Exception in Tkinter callback
Traceback (most recent call last):
File "D:\Python311\Lib\tkinter\__init__.py", line 1948, in __call__
return self.func(*args)
^^^^^^^^^^^^^^^^
File "D:\Python311\Lib\site-packages\customtkinter\windows\widgets\ctk_slider.py", line 324, in _clicked
self._command(self._output_value)
File "main.py", line 15, in get_value
self.variables.update_value()
File "main.py", line 55, in update_value
super().update_app_variable(self.variables_variable)
File "main.py", line 46, in update_app_variable
self.value_setter(size)
File "main.py", line 40, in value_setter
if self.app_condition < 1:
^^^^^^^^^^^^^^^^^^
File "D:\Python311\Lib\tkinter\__init__.py", line 2410, in __getattr__
return getattr(self.tk, attr)
^^^^^^^
File "D:\Python311\Lib\tkinter\__init__.py", line 2410, in __getattr__
return getattr(self.tk, attr)
^^^^^^^
File "D:\Python311\Lib\tkinter\__init__.py", line 2410, in __getattr__
return getattr(self.tk, attr)
^^^^^^^
[Previous line repeated 987 more times]
RecursionError: maximum recursion depth exceeded
This error occurs because the Variables
class inherits from the App
class. The update_app_variable
calls value_setter
which calls update_app_variable
creating an infinite loop.
The following modifications to the code should resolve the issue by updating app_variable_1
without the value_setter
method, instead using the self.variables_variable
value when calling update_idletasks
. This allows the GUI to update immediately.
import customtkinter
class ToplevelWindow(customtkinter.CTkToplevel):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.variables = Variables()
self.slider = customtkinter.CTkSlider(self, height=29, from_=0, to=100, number_of_steps=10, progress_color="#19A7CE", button_color="#FB2576", command=self.get_value)
self.slider.grid()
def get_value(self, value):
self.variables.variables_variable = value
self.variables.update_value(self.master)
class App(customtkinter.CTk):
def __init__(self):
super().__init__()
self.toplevel_window : customtkinter.CTkToplevel = None
self.app_variable : int = 9
self.app_variable_1 : tuple = None
self.app_variable_2 : float = 1.5
self.app_condition : float = 0.5
self.button = customtkinter.CTkButton(master=self, command=self.open_toplevel)
self.button.grid()
def open_toplevel(self):
if self.toplevel_window is None or not self.toplevel_window.winfo_exists():
self.toplevel_window = ToplevelWindow(self)
else:
self.toplevel_window.focus()
def value_setter(self, size=50):
if self.app_condition < 1:
self.app_variable_1 = (size, size * self.app_variable_2)
else:
self.app_variable_1 = (size * self.app_variable_2, size)
def update_app_variable(self, size=50):
self.value_setter(size)
class Variables:
def __init__(self):
self.variables_variable : int
def update_value(self, app_instance):
app_instance.app_variable_1 = (self.variables_variable, self.variables_variable)
app_instance.update_idletasks()
if __name__ == "__main__":
app = App()
app.mainloop()