Tkinter long-running window freezes

John O'Hagan research at johnohagan.com
Fri Feb 26 00:15:06 EST 2021


On Thu, 25 Feb 2021 21:57:19 +0100
Christian Gollwitzer <auriocus at gmx.de> wrote:

> Am 24.02.21 um 12:35 schrieb John O'Hagan:
> > Hi list
> > 
> > I have a 3.9 tkinter interface that displays data from an arbitrary
> > number of threads, each of which runs for an arbitrary period of
> > time. A frame opens in the root window when each thread starts and
> > closes when it stops. Widgets in the frame and the root window
> > control the thread and how the data is displayed.
> > 
> > This works well for several hours, but over time the root window
> > becomes unresponsive and eventually freezes and goes grey. No error
> > messages are produced in the terminal.
> > 
> > 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.  
> 
> 
> I think it is not yet clear, if this is a bug in Tkinter or in
> Tcl/Tk, the underlying scripting language. It might also be platform
> dependent. Are you on Windows? Here is an equivalent Tcl program:
> 
> ======================
> package require Tk
> 
> proc randint {} {
> 	expr {int(rand()*10000000)}
> }
> 
> proc display {label} {
> 	destroy $label
> 	set id [randint]
> 	set label [label .l$id -text [randint]]
> 	pack $label
> 	after 100 [list display $label]
> }
> 
> display [label .l]
> ========================
> 
> 
> Can you run this and check that the freeze also occurs? If you can't 
> execute the Tcl that is used by Python directly, you may also do 
> something like
> 
> 
> root = Tk()
> root.eval('Here comes the Tcl code')
> root.mainloop()
> 
> Can you also find out what version of Tcl/Tk you are using? Try
> 
> root.eval('info patchlevel')
> 
> 	Christian
> 

I've followed your suggestions as per my last post, and can confirm
the same freezing behaviour when running your code directly as a tclsh
script on Debian Testing, Tcl 8.6.11. 

I took the liberty of reducing the after delay to 10 milliseconds,
which as MRAB suggests makes the issue more obvious. (If I use 1
millisecond the numbers don't display). Over the five hours or so it was
running, the memory use increased from about 17 Mb to around 60.

Thanks

--

John



More information about the Python-list mailing list