Tkinter long-running window freezes

MRAB python at mrabarnett.plus.com
Thu Feb 25 21:26:39 EST 2021


On 2021-02-25 20:57, Christian Gollwitzer 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')
> 
I've just downloaded Tcl (Windows 10) and saw the same slow but steady 
rise in memory usage for that Tcl code (I reduced the timeout from 100 
to 1 to speed it up).

It looks like the leak, if that's what it is, is in Tcl.


More information about the Python-list mailing list