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