Tkinter long-running window freezes

Christian Gollwitzer auriocus at gmx.de
Fri Feb 26 02:19:14 EST 2021


Am 26.02.21 um 06:15 schrieb John O'Hagan:
> On Thu, 25 Feb 2021 21:57:19 +0100
> Christian Gollwitzer <auriocus at gmx.de> wrote:
>> 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.

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.

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]
========================

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


More information about the Python-list mailing list