python 为什么会出现“RecursionError:在customtkinter库中滑动CTkSlider时,超出了“最大递归深度”?

fdx2calv  于 2023-04-10  发布在  Python
关注(0)|答案(1)|浏览(135)

我试图通过Variables类将CTkSlider()的实时值从顶层传递到主窗口。我不知道是什么原因导致了这个问题。我愿意接受任何建议。这段代码有什么问题,你们认为呢?谢谢。

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()

回溯:

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
7uzetpgm

7uzetpgm1#

发生此错误是因为Variables类继承自App类。update_app_variable调用value_settervalue_setter调用update_app_variable,从而创建无限循环。
下面对代码的修改应该可以解决这个问题,方法是在不使用value_setter方法的情况下更新app_variable_1,而是在调用update_idletasks时使用self.variables_variable值。这允许GUI立即更新。

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()

相关问题