Tkinter long-running window freezes

John O'Hagan research at johnohagan.com
Fri Feb 26 18:59:24 EST 2021


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!

Thanks

-- 

John


More information about the Python-list mailing list