TKinter Destroy Question

Eric Brunel eric.brunel at pragmadev.N0SP4M.com
Thu Nov 20 11:25:20 CET 2003


Rob wrote:
> My first GUI so be gentle...
> 
> When I start my program I call a class that runs the initial window. While
> in this class if a certain button is pressed it calls a function outside the
> class. This function then initially calls another function to
> "root.destroy()". Basically I want the current window gone so the function I
> just called can open it's own window. The problem I'm stuck with is that
> once this function is done and I need to close the new window to go to the
> next window i again call the function which performs the "root.destroy()".
> When I try to call it a second time it tells me:
> 
> TclError: can't invoke "destroy" command:  application has been destroyed
> 
> How can it already be destroyed if I opened a new window in my function?
> Should I slip in somewhere a new "root.mainloop()" statment? It seems when I
> try this I get some weird results (Every command after the new
> root.mainloop() nothing happens, no buttons drawn, nothing). Is there an
> easier way to clear windows than to use the root.destroy? I've basically run
> into a nice brick wall...

Destroying the root window in a Tkinter application actually means destroying 
the whole application, not only the root window. The root window is the main 
window for the application; it is the first to pop up and must be the last to 
go. If I understand correctly, your application does not have an actual main 
window: if a second window is opened from the initial window, closing the 
initial window should not quit the application. Am I right?

If I am, the way to do that with Tkinter (or tcl/tk) is to create a fake root 
window and hide it. This window will only be used to quit the application when 
the last window is closed:

----------------------------------------------------------
from Tkinter import *

## Create main window
root = Tk()
## Hide it
root.withdraw()

## List of windows currently opened
windows = []

## Function to create a new window
def newWindow():
   ## Create window
   wdw = Toplevel()
   ## Button in window to create another new window
   Button(wdw, text='New window', command=newWindow).pack()
   ## Remember window in list of opened ones
   windows.append(wdw)
   ## When the user asks to close the window, call function closeWindow on it
   wdw.protocol('WM_DELETE_WINDOW', lambda wdw=wdw: closeWindow(wdw))

## Function called when a window's close button is clicked
def closeWindow(wdw):
   ## Actually close the window
   wdw.destroy()
   ## Remove window from list of opened ones
   if wdw in windows: windows.remove(wdw)
   ## If no more opened windows, quit application
   if not windows: root.quit()

## Create first window in application
newWindow()

## Run appliction
root.mainloop()
----------------------------------------------------------

Run the script and create a few windows. You'll see that you can close any 
window you want in any order: the application quits only when the last window is 
closed.

HTH
-- 
- Eric Brunel <eric dot brunel at pragmadev dot com> -
PragmaDev : Real Time Software Development Tools - http://www.pragmadev.com





More information about the Python-list mailing list