TKinter Destroy Question

R

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
 
M

Martin Franklin

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
 
E

Eric Brunel

Rob said:
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
 
R

Rob

Thanks for the help! I got it so that it will withdraw the current window as
i open a new one. That's exactly what i needed. I've got a pretty
complicated window maze system going now that works perfectly. You guys led
me right on track!

Next Problem....I'm trying to have the user input a number (money) in a
window and then use the number to process some information/file data. Is the
..get() the best way to do this? Again, Ive just started tinkering (or is it
Tkintering?...hehehe) with the GUI stuff so I hope my questions aren't too
simplistic. I've only started to research this since I'm still trying to get
all my menus looking right and located on the right windows for ease of use.
It seems that I might have to go buy a book since online TKinter info is not
real complete, at least for my level of understanding.

Thanks Again!
Rob
 
R

Rob

Nevermind! I've discoverd the wonderful tkSimpleDialog module and the
askfloat option....life is good.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,170
Messages
2,570,927
Members
47,469
Latest member
benny001

Latest Threads

Top