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