Strang thing in tkinter, and pdb too?

Christian Gollwitzer auriocus at gmx.de
Mon Jun 12 03:07:56 EDT 2017


Am 12.06.17 um 06:03 schrieb Terry Reedy:
> On 6/11/2017 10:06 PM, jfong at ms4.hinet.net wrote:
>>      D:\Temp\widget-tour-py3>python canvasruler.py
>>      can't invoke "event" command: application has been destroyed
>>          while executing
>>      "event generate $w <<ThemeChanged>>"
>>          (procedure "ttk::ThemeChanged" line 6)
>>          invoked from within
>>      "ttk::ThemeChanged"
> 
> I have seen this too.  It is not specific to any python/tkinter code, 
> but is specific to exiting with some things destroyed and something not.
> This must be coming from tcl or tk, not python or tkinter.

I can confirm that this is a Tk error message, with the following cause:
In Tk, the root window with the name ".", which in Python comes to live 
with the Tk() function, determines the lifetime of a program. If you  do:

	root=Tk()

an empty window appears. If now the user closes this window with the "x" 
button on top, Tk stops - because usually this means that the program 
should stop - but Tcl does continue, in order to clean up stuff before 
leaving. If now further Tk commands are sent, they give the mentioned error:

 >>> import Tkinter
 >>> root=Tkinter.Tk()
# here the window was closed using the "x" button

 >>> root
<Tkinter.Tk instance at 0x10cede6c8>
# however the Tk() object still exists,
# which is a Tcl interpreter with a dysfunct Tk

 >>> root.update()
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
   File 
"/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py", 
line 1019, in update
     self.tk.call('update')
_tkinter.TclError: can't invoke "update" command:  application has been 
destroyed
 >>>

This behaviour makes the root window special in the sense that the whole 
application stops, when it is closed, because closing this window exits 
the mainloop().

This makes sense for many applications, however sometimes it does not. 
If you wish to create many windows which pop up by themselves and the 
user can close them freely, then one should withdraw the main window:

	root=Tkinter.Tk()
	root.withdraw()

now the main window disappears, the user can't incidentally close it. 
One can then create additional toplevel windows using
	
	t=Tkinter.Toplevel()

and place anything there. These can be closed without destroying the 
application / exiting the main loop.

	Christian




More information about the Python-list mailing list