TomSchimansky / CustomTkinter

A modern and customizable python UI-library based on Tkinter
MIT License
10.77k stars 1.03k forks source link

Exceeded recursion limit while rescaling #2451

Closed Loloncio closed 1 month ago

Loloncio commented 1 month ago

So I have this code: `import customtkinter as ctk import ctypes

def rescale(event, root, frames, scrolls): scale_factor = ctypes.windll.shcore.GetScaleFactorForDevice(0)/100 print(scale_factor) width = root.winfo_width()//scale_factor height = root.winfo_height()//scale_factor print("Width = ", width, "Height = ", height, "type", type(width)) for i in range(3): frames[i].configure(width = width-10,height=(height//3)-30) scrolls[i].configure(width = (width/2)-40,height=(height//3)-50) scrolls[i+3].configure(width = (width/2)-40,height=(height//3)-50)

Updates window

    root.update_idletasks()

if name == "main": root = ctk.CTk() root.geometry("1280x720") root.minsize(width=1280,height=720) root.title("Test") root.configure(fg_color = "#4B4B4B") height = 720 width = 1280

frames, scrolls, labels = [], [], []

leftFont = ctk.CTkFont(family="Inter", size=20, weight="normal")
rightFont = ctk.CTkFont(family="Inter", size=15, weight="normal")

# Base frames creation
for i in range(3):
    frames.append(ctk.CTkFrame(master=root,fg_color="#504F4F", corner_radius=10, width = width-10, height=height/3-46))
# ScrollFrames creation
for i in range(6):
    scrolls.append(ctk.CTkScrollableFrame(master=frames[i%3],fg_color="#504F4F", corner_radius= 10,width = ((width/2)-40)))
# Buttons creation
button1 = ctk.CTkButton(root, text="button1", font=leftFont, corner_radius=10,
                            fg_color="#1E1E1E", text_color="white", height=40)
button2 = ctk.CTkButton(root, text="button2", font=leftFont, corner_radius=10,
                            fg_color="#1E1E1E", text_color="white", height=40)
button3 = ctk.CTkButton(root, text="button3", font=leftFont, corner_radius=10,
                            fg_color="#1E1E1E", text_color="white", height=40)
# Placing of buttons
button1.grid(column = 0, row = 3,pady = 5, padx = 10, sticky="w")
button2.grid(column = 1, row = 3,pady = 5, padx = 10, sticky="w")
button3.grid(column = 1, row = 3,pady = 5, sticky="e")
# Frames placing
for i in range(3):
    frames[i].grid(column= 0, row = i, columnspan=2, padx=3, pady=3,)
# Scrolls and labels placing
for i in range(3):
    scrolls[i].grid(row = 0, column=0, padx = 5)
    scrolls[i+3].grid(row = 0, column=1, padx = 5)
# Bind rescale method
root.bind("<Configure>", lambda event, root = root, frames = frames, scrolls = scrolls: rescale(event, root, frames, scrolls))
root.mainloop()`

When I resize the window the method rescale is called and it should rescale the window but it throws this error:

`Traceback (most recent call last): File "C:\ProgramData\miniconda3\envs\AppPerm\lib\tkinter__init.py", line 1921, in call__ return self.func(*args) File "d:\TFG\Python\App-Perm\test.py", line 56, in root.bind("", lambda event, root = root, frames = frames, scrolls = scrolls: rescale(event, root, frames, scrolls)) File "d:\TFG\Python\App-Perm\test.py", line 11, in rescale frames[i].configure(width = width-10,height=(height//3)-30) File "C:\Users\aleja\AppData\Roaming\Python\Python310\site-packages\customtkinter\windows\widgets\ctk_frame.py", line 167, in configure super().configure(require_redraw=require_redraw, **kwargs) File "C:\Users\aleja\AppData\Roaming\Python\Python310\site-packages\customtkinter\windows\widgets\core_widget_classes\ctk_base_class.py", line 117, in configure self._set_dimensions(width=kwargs.pop("width")) File "C:\Users\aleja\AppData\Roaming\Python\Python310\site-packages\customtkinter\windows\widgets\ctk_frame.py", line 88, in _set_dimensions super()._set_dimensions(width, height) File "C:\Users\aleja\AppData\Roaming\Python\Python310\site-packages\customtkinter\windows\widgets\core_widget_classes\ctk_base_class.py", line 240, in _set_dimensions super().configure(width=self._apply_widget_scaling(self._desired_width), RecursionError: maximum recursion depth exceeded while calling a Python object

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "d:\TFG\Python\App-Perm\test.py", line 57, in root.mainloop() File "C:\Users\aleja\AppData\Roaming\Python\Python310\site-packages\customtkinter\windows\ctk_tk.py", line 165, in mainloop super().mainloop(*args, **kwargs) File "C:\ProgramData\miniconda3\envs\AppPerm\lib\tkinter__init.py", line 1458, in mainloop self.tk.mainloop(n) File "C:\ProgramData\miniconda3\envs\AppPerm\lib\tkinter\init.py", line 1925, in call self.widget._report_exception() File "C:\ProgramData\miniconda3\envs\AppPerm\lib\tkinter\init.py", line 1641, in _report_exception root.report_callback_exception(exc, val, tb) File "C:\ProgramData\miniconda3\envs\AppPerm\lib\tkinter\init.py", line 2379, in report_callback_exception traceback.print_exception(exc, val, tb) File "C:\ProgramData\miniconda3\envs\AppPerm\lib\traceback.py", line 119, in print_exception te = TracebackException(type(value), value, tb, limit=limit, compact=True) File "C:\ProgramData\miniconda3\envs\AppPerm\lib\traceback.py", line 502, in init__ self.stack = StackSummary.extract( File "C:\ProgramData\miniconda3\envs\AppPerm\lib\traceback.py", line 353, in extract limit = getattr(sys, 'tracebacklimit', None) RecursionError: maximum recursion depth exceeded while calling a Python object`

If i change frames[i].configure(width = width-10,height=(height//3)-30) with frames[i].configure(width = width-10,height=(height//3)-35), it does work. Also removing the correction for rescaling works but that makes the app to not look right, it makes widgets bigger than the window.

Not sure if this is a bug or something i am doing wrong but it would be nice to know.

Loloncio commented 1 month ago

Never mind, the problem is that the method rescale is being called to many times since all the changes in the for of that function generates de rescale event again, the solution has been to place a condition where the rescaling is only done if more than half a second has passed since the last rescaling