Tkinter long-running window freezes
John O'Hagan
research at johnohagan.com
Thu Feb 25 19:09:23 EST 2021
On Thu, 25 Feb 2021 11:06:05 -0500
Richard Damon <Richard at Damon-Family.org> wrote:
> On 2/24/21 6:35 AM, John O'Hagan wrote:
> > Here is some minimal, non-threaded code that reproduces the problem
> > on my system (Xfce4 on Debian testing):
> >
> > from tkinter import *
> > from random import randint
> >
> > root = Tk()
> >
> > def display(label):
> > label.destroy()
> > label = Label(text=randint(0, 9))
> > label.pack()
> > root.after(100, display, label)
> >
> > display(Label())
> > mainloop()
> >
> > This opens a tiny window that displays a random digit on a new label
> > every .1 second. (Obviously I could do this by updating the text
> > rather than recreating the label, but my real application has to
> > destroy widgets and create new ones).
> >
> > This works for 3-4 hours, but eventually the window freezes.
> >
> > The process uses about 26 Mb of memory at first, and this gradually
> > increases to around 30 or so by the time it freezes.
> >
> > Any ideas what could be causing this, or even how to approach
> > debugging or workarounds?
> >
> > Thanks
> >
> > --
> >
> > John
>
> One thought is that repeatedly destroying and recreating a label might
> be leaking a resource. One option would be to change the code to just
> update the label rather than recreating it each time. Simplest is
> probably to link the Label to a StringVar instead of a fixed text and
> updating the variable to change the text. You can also (I believe) go
> into the Label and change the text it has with a configuration call.
>
Thanks for your reply.
It's true that your suggested approach stops the leak (if that's what
it is!) in the example code, but IMO there are valid use-cases
where it's necessary (or at least desirable) to continually create new
widgets and then destroy them in the course of running the application.
In my use-case, the application reads YOLO object-recognition data from
video, and displays data about each new object in a new frame. When the
object ceases to be visible, the frame is destroyed.
I suppose I could redesign, e.g. by withdrawing frames instead of
destroying them, and keeping them in a pool to re-use later for new
data streams as needed. I'll give that a try if I can't solve this
issue.
Thanks
--
John
More information about the Python-list
mailing list