python / cpython

The Python programming language
https://www.python.org
Other
63.49k stars 30.41k forks source link

Tkinter Memory Leak when updating any UI elements most noticeable when updating label images, only present on windows #124364

Open maj113 opened 1 month ago

maj113 commented 1 month ago

Bug report

Bug description:

Minimal-ish reproducible example:

import tkinter as tk
from itertools import cycle

root = tk.Tk()

# Any GIF should work
gif_path = r""

frames = []
for i in range(100):
    try:
        # Using PIL and ImageTk has no difference
        gif = tk.PhotoImage(file=gif_path, format=f'gif -index {i}') 
        frames.append(gif.subsample(1, 1).copy()) 
    except tk.TclError:
        break

label = tk.Label(root)
label.pack()

frame_cycle = cycle(frames)

def update_frame():
    frame = next(frame_cycle)
    label.config(image=frame)
    # Happens with other update times however more updates = faster memory leak
    root.after(1, update_frame)

root.after(0, update_frame)

root.mainloop()

While the leak is most noticeable when updating a label it also happens when scrolling a text widget with labels that have images

https://github.com/user-attachments/assets/6c48824c-64f9-4232-b730-5b1e31beb084

Here it is increasing just by scrolling over the paused gifs (static images)

https://github.com/user-attachments/assets/3d7b6d0f-abd1-44a5-9a44-c1781d15d081

Note that the recording is filmed at much lower fps, appearing slower than it is

I was unable to narrow the leak down, tracemalloc didn't show anything of use (possibly an issue in tcl/tk?)

CPython versions tested on:

3.12, 3.13

Operating systems tested on:

Linux, Windows

maj113 commented 1 month ago

Also happening in IDLE:

https://github.com/user-attachments/assets/8ec13569-beec-4216-923a-d37ebca570b7