468,772 Members | 2,271 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,772 developers. It's quick & easy.

TKinter Destroy Question

Rob
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...

Thanks for the help!
Rob
Jul 18 '05 #1
2 25410
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

Jul 18 '05 #2
On Thu, 2003-11-20 at 04:59, 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

When you destroy a window it's gone! so can't be destroyed again.....
Without an example of what you are doing it's difficult to help but.
You could call withdraw() method on root this will unmap it from the
screen (but not destroy it) However why are you calling destroy on root
twice? Perhaps you mean to call destroy on the old window when you
create a new one (like a Wizard)
e.g (untested...)

root=Tk()

def createNext():
nextWindow = Toplevel()
nextWindow.title("Next Window")
b = Button(root, text="Create Next Window", command=createNext)
b.pack()
root.withdraw()
root.title("The Main Root Window")
b = Button(root, text="Create Next Window", command=createNext)
b.pack()
root.mainloop()
The problem here is you are not getting rid of the previous window when
the Next button is pressed just root!
Perhaps a better example would be:-
class MyApplication(Tk):
def __init__(self):
Tk.__init__(self)
self.title("Main Application Window")
self.prevWindow = self
self.windowCount = 1
b = Button(self, text="Next", command=self.nextWindow)
b.pack()

def nextWindow(self):
window = Toplevel()
self.windowCount = self.windowCount + 1
window.title("Next Window %d" %self.windowCount)
b = Button(window, text="Next", command=self.nextWindow)
b.pack()
self.prevWindow.withdraw()
self.prevWindow = window


app = MyApplication()
app.mainloop()
However this will never finish! to close the whole application the
app.quit() method must be called..... or if it's inside the class
definition self.quit()

Basically explain what you want with some example code and we can help

Regards
Martin
--
Martin Franklin <mf********@gatwick.westerngeco.slb.com>
Jul 18 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

5 posts views Thread by Andrew Gregory | last post: by
3 posts views Thread by Mickel Grönroos | last post: by
6 posts views Thread by max(01)* | last post: by
5 posts views Thread by max(01)* | last post: by
reply views Thread by Stewart Midwinter | last post: by
1 post views Thread by Michael Yanowitz | last post: by
3 posts views Thread by joshdw4 | last post: by
3 posts views Thread by J-Burns | last post: by
reply views Thread by nicstel | last post: by
1 post views Thread by CARIGAR | last post: by
2 posts views Thread by Marin | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.