Tkinter long-running window freezes

MRAB python at mrabarnett.plus.com
Fri Feb 26 22:02:55 EST 2021


On 2021-02-27 02:38, John O'Hagan wrote:
> On Sat, 27 Feb 2021 01:06:06 +0000
> MRAB <python at mrabarnett.plus.com> wrote:
> 
>> On 2021-02-26 23:59, John O'Hagan wrote:
>> > On Fri, 26 Feb 2021 08:19:14 +0100
>> > Christian Gollwitzer <auriocus at gmx.de> wrote:
>> >   
>> >> Am 26.02.21 um 06:15 schrieb John O'Hagan:  
>> > [...]  
>> >> > 
>> >> > 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.    
>> >> 
>> >> You might report this as a bug to the Tcl bugtracker 
>> >> https://core.tcl-lang.org/tk/ticket
>> >> 
>> >> I guess the problem is with the steady creation of widgets. Tk was
>> >> not meant to be used like that. Tkinter creates new widget names
>> >> for each widget with random numbers, just like the Tcl code above
>> >> does, whereas in a usual Tcl/Tk program the names are given by the
>> >> programmer.  
>> > 
>> > Thanks, I will make the bug report. However, based  on your comments
>> > above, it looks similar to this one, closed as invalid 16 years ago:
>> > 
>> > https://core.tcl-lang.org/tk/tktview/1173484fffffffffffff
>> > 
>> > This was also related to memory "creep" caused by Tk's cache of
>> > names, which AIUI is a Tk design feature (but I don't know Tk!).
>> >   
>> >> Can you also check this program, which reuses the same widget path
>> >> name, albeit does the creation/destruction in cycles:
>> >> 
>> >> ======================
>> >> package require Tk
>> >> 
>> >> proc randint {} {
>> >>      expr {int(rand()*10000000)}
>> >> }
>> >> 
>> >> proc display {label} {
>> >>      destroy $label
>> >>      set label [label .l -text [randint]]
>> >>      pack $label
>> >>      after 100 [list display $label]
>> >> }
>> >> 
>> >> display [label .l]
>> >> ========================
>> >>   
>> > 
>> > I have tried this overnight and it is still running, not frozen and
>> > with no apparent increase in memory use. I guess that is likely the
>> > issue. I don't know Tcl/Tk - is there a way to emulate the above
>> > approach of re-using the widget name in tkinter?
>> >   
>> >> As mentioned by others, typically you wouldn't continuously
>> >> recreate new widgets, but either update the text of the widget
>> >> (label['text']="New text") or attaching a StringVar() )
>> >> 
>> >> or, if you must rearrange the widgets, you pack_forget() them and
>> >> then repack them.
>> >> 
>> >> 	Christian  
>> > 
>> > This is possible of course, but will require more than a repack. In
>> > my use case, each widget is an attribute of a Python object,
>> > intended control and display data about that object, and there is an
>> > indeterminate number of such objects at any given time. I had
>> > assumed I could just destroy the widget and let the object go out of
>> > scope to be garbage collected. I'll need to redesign this
>> > altogether if I can't rely on Tk to manage memory.
>> > 
>> > IMHO it's quite surprising if .destroy doesn't free all the
>> > resources used by a widget!
>> >   
>> I've look in Lib\tkinter\__init__.py and it appears that you can give
>> it a name, so:
>> 
>> from tkinter import *
>> from random import randint
>> 
>> root = Tk()
>> 
>> def display(label):
>>       label.destroy()
>>       label = Label(name='my_label', text=randint(0, 9))
>>       label.pack()
>>       root.after(1, display, label)
>> 
>> display(Label(name='my_label'))
>> mainloop()
>> 
>> When I do that I'm not seeing a memory rise.
> 
> I just did the exact same thing, also saw no memory rise, but the
> window still froze after a couple of hours. Did your window freeze?
> Maybe the memory rise and the freeze are unrelated after all.
> 
> Also, I was mistaken about Christian's second version of the Tcl code
> above - there is no memory rise but the window also freezes after a
> while. Suggests the problem is in Tcl/Tk.
> 
I didn't run it for that long, only long enough to compare it with the 
previous version. (Both were started at the same time.)


More information about the Python-list mailing list