FAQ
Could someone help me out with these few lines of code: I would like
to know why the Quit button in this application removes the buttons
and causes "Quitting" to be printed, but does not close the outer
frame.

Andrew.


# Demonstration TK interface Windows application
# Runs ok from within IDLE
#
from Tkinter import *

class CommonStuff: # to get common access to variables and functions
def __init__(cself, frame):
cself.frame = frame

def say_hi(cself):
print "Hello all"


class MyWidgets(Frame, CommonStuff):
def __init__(wself, CS):
Frame.__init__(wself, CS.frame)
wself.quitbutton = Button(wself)
wself.quitbutton["text"] = "Quit"
wself.quitbutton["fg"] = "red"
wself.quitbutton["command"] = wself.destroy

wself.quitbutton.pack({"side": "left"})

wself.hi_there = Button(wself)
wself.hi_there["text"] = "Hello",
wself.hi_there["command"] = CS.say_hi

wself.hi_there.pack({"side": "left"})


class Application:
def __init__(self, master):
self.frame=Frame(master)
CS = CommonStuff(self.frame)

displayedwidget=MyWidgets(CS)
displayedwidget.grid(row=0, column=0)
self.frame.grid(row=0, column=0)
self.frame.columnconfigure(0)
displayedwidget.bind("<Destroy>", self.quit)
self.frame.update()

def quit(self, event):
print"Quitting..."
self.frame.destroy # Destroy frame and all children


root = Tk()
mainWin = Application(root)
root.wait_window(mainWin.frame)

Search Discussions

  • Eric Brunel at Aug 1, 2003 at 10:01 am

    Andrew Gregory wrote:
    Could someone help me out with these few lines of code: I would like
    to know why the Quit button in this application removes the buttons
    and causes "Quitting" to be printed, but does not close the outer
    frame.

    Andrew.


    # Demonstration TK interface Windows application
    # Runs ok from within IDLE
    #
    from Tkinter import *

    class CommonStuff: # to get common access to variables and functions
    def __init__(cself, frame):
    cself.frame = frame
    It is a Bad Idea to give the first parameter of a method any other name than
    "self"... Checking tools like PyChecker will complain if you do that, and your
    programs will be harder to read for anyone else doing Python...
    def say_hi(cself):
    print "Hello all"


    class MyWidgets(Frame, CommonStuff):
    def __init__(wself, CS):
    Frame.__init__(wself, CS.frame)
    Where have you found this type of Tkinter object initialization? Apparently,
    there are weird style guides lying around somewhere... You can rewrite all of this:
    wself.quitbutton = Button(wself)
    wself.quitbutton["text"] = "Quit"
    wself.quitbutton["fg"] = "red"
    wself.quitbutton["command"] = wself.destroy

    wself.quitbutton.pack({"side": "left"})
    like that:

    wself.quitbutton = Button(wself, text='Quit', fg='red', command=wself.destroy)
    wself.quitbutton.pack(side=LEFT)

    This is the most common way to do things. BTW, since you never do anything to
    the buttons themselves ouside this method, there's no need at all to store them
    in attributes. So you can just do:

    quitbutton = Button(wself, text='Quit', fg='red', command=wself.destroy)
    quitbutton.pack(side=LEFT)

    or even:

    Button(wself, text='Quit', fg='red', command=wself.destroy).pack(side=LEFT)
    wself.hi_there = Button(wself)
    wself.hi_there["text"] = "Hello",
    wself.hi_there["command"] = CS.say_hi

    wself.hi_there.pack({"side": "left"})
    Same here:

    wself.hi_there = Button(wself, text="Hello", command=CS.say_hi)
    wself.hi_there.pack(side=LEFT)

    or:

    hi_there = Button(wself, text="Hello", command=CS.say_hi)
    hi_there.pack(side=LEFT)

    or even:

    Button(wself, text="Hello", command=CS.say_hi).pack(side=LEFT)
    class Application:
    def __init__(self, master):
    self.frame=Frame(master)
    CS = CommonStuff(self.frame)

    displayedwidget=MyWidgets(CS)
    displayedwidget.grid(row=0, column=0)
    self.frame.grid(row=0, column=0)
    self.frame.columnconfigure(0)
    This statement is a no-op: you say you'll configure the column n#0 of
    self.frame, but you do not give any features for the column. What are you trying
    to do?
    displayedwidget.bind("<Destroy>", self.quit)
    self.frame.update()

    def quit(self, event):
    print"Quitting..."
    self.frame.destroy # Destroy frame and all children
    Compare this line to the last in the __init__ method just above. To call the
    update method on self.frame, you did self.frame.update(). So to call the destroy
    method on self.frame, you must do self.frame.destroy(). self.frame.destroy
    merely returns the destroy method of the self.frame object, but doesn't do
    anything with it.
    root = Tk()
    mainWin = Application(root)
    root.wait_window(mainWin.frame)
    I don't know if this works, but I know it's not the usual way to run a Tkinter
    application. You'd better replace the last line by:

    root.mainloop()

    HTH

    --
    - Eric Brunel <eric.brunel at pragmadev.com> -
    PragmaDev : Real Time Software Development Tools - http://www.pragmadev.com
  • Andrew Gregory at Aug 4, 2003 at 10:01 am
    Many thanks for such a comprehensive answer.

    Altered root.wait_window(mainWin.frame) to root.mainloop()
    and found that it runs and closes ok within IDLE. I seem to remember
    having crashes on closing within IDLE before.

    I did try self.frame.destroy as the function
    self.frame.destroy(), but the Quit button still didn't work. The
    application can be closed via the window corner X, but I'm still
    puzzled as to why it does not respond to Quit.

    Any more suggestions?


    Updated code below, Andrew.



    # Demonstration TK interface Windows application
    # Runs ok from within IDLE
    #
    from Tkinter import *

    class CommonStuff: # to get common access to variables and functions
    def __init__(self, frame):
    self.frame = frame

    def say_hi(self):
    print "Hello all"


    class MyWidgets(Frame, CommonStuff):
    def __init__(self, CS):
    Frame.__init__(self, CS.frame)
    self.quitbutton = Button(self, text='Quit', fg='red',
    command=self.destroy)
    self.quitbutton.pack(side=LEFT)
    self.hi_there = Button(self, text='Hello', command=CS.say_hi)
    self.hi_there.pack(side=LEFT)


    class Application:
    def __init__(self, master):
    self.frame=Frame(master)
    CS = CommonStuff(self.frame)

    displayedwidget=MyWidgets(CS)
    displayedwidget.grid(row=0, column=0)
    self.frame.grid(row=0, column=0)
    displayedwidget.bind("<Destroy>", self.quit)
    self.frame.update()

    def quit(self, event):
    print"Quitting..."
    self.frame.destroy() # Destroy frame and all children


    root = Tk()
    mainWin = Application(root)
    root.mainloop()
  • Klappnase at Aug 4, 2003 at 11:44 pm


    # Demonstration TK interface Windows application
    # Runs ok from within IDLE
    #
    from Tkinter import *

    class CommonStuff: # to get common access to variables and functions
    def __init__(self, frame):
    self.frame = frame

    def say_hi(self):
    print "Hello all"


    class MyWidgets(Frame, CommonStuff):
    def __init__(self, CS):
    Frame.__init__(self, CS.frame)
    self.quitbutton = Button(self, text='Quit', fg='red',
    command=self.destroy)
    self.quitbutton.pack(side=LEFT)
    self.hi_there = Button(self, text='Hello', command=CS.say_hi)
    self.hi_there.pack(side=LEFT)


    class Application:
    def __init__(self, master):
    self.frame=Frame(master)
    CS = CommonStuff(self.frame)

    displayedwidget=MyWidgets(CS)
    displayedwidget.grid(row=0, column=0)
    self.frame.grid(row=0, column=0)
    displayedwidget.bind("<Destroy>", self.quit)
    self.frame.update()

    def quit(self, event):
    print"Quitting..."
    self.frame.destroy() # Destroy frame and all children


    root = Tk()
    mainWin = Application(root)
    root.mainloop()
    I think you could have it easier, if you just want to exit you
    application with the quit button:

    class MyWidgets(Frame, CommonStuff):
    def __init__(self, CS):
    Frame.__init__(self, CS.frame)
    self.quitbutton = Button(self, text='Quit', fg='red',
    command=self.quit)
    self.quitbutton.pack(side=LEFT)
    self.hi_there = Button(self, text='Hello', command=CS.say_hi)
    self.hi_there.pack(side=LEFT)

    def quit(self):
    print "Quitting..."
    sys.exit(0)

    If you want to run it from within the interpreter (I am not sure if it
    is that what you are trying) the following might work too:

    class Application:
    def __init__(self, master):
    self.frame=Frame(master)
    CS = CommonStuff(self.frame)

    displayedwidget=MyWidgets(CS)
    displayedwidget.grid(row=0, column=0)
    self.frame.grid(row=0, column=0)
    displayedwidget.bind("<Destroy>", self.quit)
    self.frame.update()

    self.master = master

    def quit(self, event):
    print"Quitting..."
    self.master.destroy() # Destroy root window

    However I would recommend to store the code in a file and then run the
    file.
    I am sorry that I cannot give you more detailed advice, but I am still
    a beginner, too. I hope this helped anyway.

    Good luck!

    Michael
  • Eric Brunel at Aug 5, 2003 at 7:40 am

    klappnase wrote:

    # Demonstration TK interface Windows application
    # Runs ok from within IDLE
    #
    from Tkinter import *

    class CommonStuff: # to get common access to variables and functions
    def __init__(self, frame):
    self.frame = frame

    def say_hi(self):
    print "Hello all"


    class MyWidgets(Frame, CommonStuff):
    def __init__(self, CS):
    Frame.__init__(self, CS.frame)
    self.quitbutton = Button(self, text='Quit', fg='red',
    command=self.destroy)
    self.quitbutton.pack(side=LEFT)
    self.hi_there = Button(self, text='Hello', command=CS.say_hi)
    self.hi_there.pack(side=LEFT)


    class Application:
    def __init__(self, master):
    self.frame=Frame(master)
    CS = CommonStuff(self.frame)

    displayedwidget=MyWidgets(CS)
    displayedwidget.grid(row=0, column=0)
    self.frame.grid(row=0, column=0)
    displayedwidget.bind("<Destroy>", self.quit)
    self.frame.update()

    def quit(self, event):
    print"Quitting..."
    self.frame.destroy() # Destroy frame and all children


    root = Tk()
    mainWin = Application(root)
    root.mainloop()

    I think you could have it easier, if you just want to exit you
    application with the quit button:

    class MyWidgets(Frame, CommonStuff):
    def __init__(self, CS):
    Frame.__init__(self, CS.frame)
    self.quitbutton = Button(self, text='Quit', fg='red',
    command=self.quit)
    self.quitbutton.pack(side=LEFT)
    self.hi_there = Button(self, text='Hello', command=CS.say_hi)
    self.hi_there.pack(side=LEFT)

    def quit(self):
    print "Quitting..."
    sys.exit(0)
    This works, but actuallly quits the application immediatly. So if you happen to
    have code after the call to the Tk mainloop, it won't be executed, which might
    not be what you want. Moreover, there's already a quit method defined on
    MyWidgets, inherited from Frame, that does exactly what you want: quitting the
    Tk mainloop. So you could just do:

    def quit(self):
    print "Quitting..."
    Frame.quit(self)
    If you want to run it from within the interpreter (I am not sure if it
    is that what you are trying) the following might work too:

    class Application:
    def __init__(self, master):
    self.frame=Frame(master)
    CS = CommonStuff(self.frame)

    displayedwidget=MyWidgets(CS)
    displayedwidget.grid(row=0, column=0)
    self.frame.grid(row=0, column=0)
    displayedwidget.bind("<Destroy>", self.quit)
    self.frame.update()

    self.master = master

    def quit(self, event):
    print"Quitting..."
    self.master.destroy() # Destroy root window
    This may also work, but the most common way is the one I describe above. If you
    want to do it here, you can do:

    def quit(self, event):
    print "Quitting..."
    self.master.quit()

    AFAIK, all Tkinter widgets have a quit method that will quit the Tk mainloop.

    HTH
    --
    - Eric Brunel <eric.brunel at pragmadev.com> -
    PragmaDev : Real Time Software Development Tools - http://www.pragmadev.com
  • Klappnase at Aug 5, 2003 at 3:20 pm
    Eric Brunel <eric.brunel at pragmadev.com> wrote in message news:<bgnmjv$omq$1 at news-reader4.wanadoo.fr>...
    This may also work, but the most common way is the one I describe above. If you
    want to do it here, you can do:

    def quit(self, event):
    print "Quitting..."
    self.master.quit()

    AFAIK, all Tkinter widgets have a quit method that will quit the Tk mainloop.

    HTH
    I think Tkinter's quit() method will not work while running from
    within the interpreter, because there is no mainloop. I think you will
    have to destroy() there.

    Best regards

    Michael
  • Kevin Burrows at Aug 6, 2003 at 12:53 pm
    If I follow this thread correctly we are discussing how the exit from
    Python/Tkinter programs. As it happens I have beed experimenting with
    these environments and have struck the same problem.Examples from
    "Python and Tkinter Programming" by John E Grayson. These examples
    fire up OK but when the Quit button is hit the window freezes. If the
    X in the window corner is hit first the application exits correctly.

    Several suggestions have been suggested. I have experimented with the
    following program:

    #!/usr/local/bin/python
    from Tkinter import * # Interface to Tk widgets

    class Application(Frame):
    def __init__(self, master=None):
    Frame.__init__(self, master)
    self.grid()
    self.createWidgets()

    def createWidgets(self):
    self.quitButton = Button ( self, text="Quit",
    command=self.quit )
    self.quitButton.grid()

    def quit(self):
    print sys.platform
    print "Quitting"
    self.quit #--DOES NOT QET RID OF WINDOW
    # sys.exit(0) #--DOES NOT GET RID OF WINDOW
    # self.master.destroy() #--GETS RID OF WINDOW

    app = Application() # Instantiate the application class
    app.master.title("Sample application")
    app.mainloop() # Wait for events

    I changed commented out 2 of the 3 methods in the "quit" function
    under PythonWinIDE, IDLE and Windows using a .pyw extension.

    The results of the quit methods were:

    PythonWinIDE IDLE Windows using
    a .pyw extension

    quit No No No

    sys.exit No No Yes

    destroy No No Yes

    Interstingly the application does not freeze under IDLE and can still
    be closed with the windows X.

    I am using Windows 98 and Python 2.2

    So it looks like "destroy" is the method that works. It is
    interesting that the example and test in the Tkinter.py module use the
    "destroy" method but Grayson uses "quit" in his examples. Perhapse
    the problem with "quit" is a MS Windows thing.

    I would be interested to here if the same thing happens under Unix et.
    al.

    Kevin

    On Tue, 05 Aug 2003 09:40:55 +0200, Eric Brunel
    wrote:

    Most deleted

    def quit(self, event):
    print"Quitting..."
    self.master.destroy() # Destroy root window
    This may also work, but the most common way is the one I describe above. If you
    want to do it here, you can do:

    def quit(self, event):
    print "Quitting..."
    self.master.quit()

    AFAIK, all Tkinter widgets have a quit method that will quit the Tk mainloop.

    HTH
    --
    - Eric Brunel <eric.brunel at pragmadev.com> -
    PragmaDev : Real Time Software Development Tools - http://www.pragmadev.com
  • Eric Brunel at Aug 6, 2003 at 2:35 pm

    Kevin Burrows wrote:
    If I follow this thread correctly we are discussing how the exit from
    Python/Tkinter programs. As it happens I have beed experimenting with
    these environments and have struck the same problem.Examples from
    "Python and Tkinter Programming" by John E Grayson. These examples
    fire up OK but when the Quit button is hit the window freezes. If the
    X in the window corner is hit first the application exits correctly.

    Several suggestions have been suggested. I have experimented with the
    following program:

    #!/usr/local/bin/python
    from Tkinter import * # Interface to Tk widgets

    class Application(Frame):
    def __init__(self, master=None):
    Frame.__init__(self, master)
    self.grid()
    self.createWidgets()

    def createWidgets(self):
    self.quitButton = Button ( self, text="Quit",
    command=self.quit )
    self.quitButton.grid()

    def quit(self):
    print sys.platform
    print "Quitting"
    self.quit #--DOES NOT QET RID OF WINDOW
    # sys.exit(0) #--DOES NOT GET RID OF WINDOW
    # self.master.destroy() #--GETS RID OF WINDOW
    This can't be the code you tested, since, again, there are no () after
    self.quit. Moreover, even if you had written self.quit(), it wouldn't have
    worked since this would call again the quit method on Application recursively,
    ending up in an exception. What you should have written is:

    Frame.quit(self)
    app = Application() # Instantiate the application class
    app.master.title("Sample application")
    app.mainloop() # Wait for events

    I changed commented out 2 of the 3 methods in the "quit" function
    under PythonWinIDE, IDLE and Windows using a .pyw extension.

    The results of the quit methods were:

    PythonWinIDE IDLE Windows using
    a .pyw extension

    quit No No No

    sys.exit No No Yes

    destroy No No Yes

    Interstingly the application does not freeze under IDLE and can still
    be closed with the windows X.

    I am using Windows 98 and Python 2.2
    There always have been issues with Tkinter on Windows 98: Tkinter applications
    often freeze on exit, but not always. This is likely to be a Windows issue,
    since it works everywhere else, even on more recent version of Windows with the
    same tcl/tk version.
    So it looks like "destroy" is the method that works. It is
    interesting that the example and test in the Tkinter.py module use the
    "destroy" method but Grayson uses "quit" in his examples. Perhapse
    the problem with "quit" is a MS Windows thing.
    You definetely should use quit: quitting Tkinter's main loop is its intended
    use; see
    http://www.pythonware.com/library/tkinter/introduction/x9374-event-processing.htm
    I would be interested to here if the same thing happens under Unix et.
    al.
    I never had any problem with the quit method on Unix (Linux or Solaris) or on
    recent version of Windows (2k, XP). I'm however always running the Python
    scripts from the command line, never from an IDE. So that may be an issue too...
    --
    - Eric Brunel <eric.brunel at pragmadev.com> -
    PragmaDev : Real Time Software Development Tools - http://www.pragmadev.com
  • Mark Daley at Aug 6, 2003 at 5:27 pm
    I have problems with sys.exit() when I'm running under IDLE, since it seems
    to cause ALL mainloops to exit, killing IDLE. I can't really give a whole
    lot of detail on this, since I tend to use the command line to launch my
    GUIs, anyway.

    - Mark

    -----Original Message-----
    From: python-list-admin at python.org
    [mailto:python-list-admin at python.org]On Behalf Of Eric Brunel
    Sent: Wednesday, August 06, 2003 7:35 AM
    To: python-list at python.org
    Subject: Re: Tkinter programming problem


    Kevin Burrows wrote:
    If I follow this thread correctly we are discussing how the exit from
    Python/Tkinter programs. As it happens I have beed experimenting with
    these environments and have struck the same problem.Examples from
    "Python and Tkinter Programming" by John E Grayson. These examples
    fire up OK but when the Quit button is hit the window freezes. If the
    X in the window corner is hit first the application exits correctly.

    Several suggestions have been suggested. I have experimented with the
    following program:

    #!/usr/local/bin/python
    from Tkinter import * # Interface to Tk widgets

    class Application(Frame):
    def __init__(self, master=None):
    Frame.__init__(self, master)
    self.grid()
    self.createWidgets()

    def createWidgets(self):
    self.quitButton = Button ( self, text="Quit",
    command=self.quit )
    self.quitButton.grid()

    def quit(self):
    print sys.platform
    print "Quitting"
    self.quit #--DOES NOT QET RID OF WINDOW
    # sys.exit(0) #--DOES NOT GET RID OF WINDOW
    # self.master.destroy() #--GETS RID OF WINDOW
    This can't be the code you tested, since, again, there are no () after
    self.quit. Moreover, even if you had written self.quit(), it wouldn't have
    worked since this would call again the quit method on Application
    recursively,
    ending up in an exception. What you should have written is:

    Frame.quit(self)
    app = Application() # Instantiate the application class
    app.master.title("Sample application")
    app.mainloop() # Wait for events

    I changed commented out 2 of the 3 methods in the "quit" function
    under PythonWinIDE, IDLE and Windows using a .pyw extension.

    The results of the quit methods were:

    PythonWinIDE IDLE Windows using
    a .pyw extension

    quit No No No

    sys.exit No No Yes

    destroy No No Yes

    Interstingly the application does not freeze under IDLE and can still
    be closed with the windows X.

    I am using Windows 98 and Python 2.2
    There always have been issues with Tkinter on Windows 98: Tkinter
    applications
    often freeze on exit, but not always. This is likely to be a Windows issue,
    since it works everywhere else, even on more recent version of Windows with
    the
    same tcl/tk version.
    So it looks like "destroy" is the method that works. It is
    interesting that the example and test in the Tkinter.py module use the
    "destroy" method but Grayson uses "quit" in his examples. Perhapse
    the problem with "quit" is a MS Windows thing.
    You definetely should use quit: quitting Tkinter's main loop is its intended
    use; see
    http://www.pythonware.com/library/tkinter/introduction/x9374-event-processin
    g.htm
    I would be interested to here if the same thing happens under Unix et.
    al.
    I never had any problem with the quit method on Unix (Linux or Solaris) or
    on
    recent version of Windows (2k, XP). I'm however always running the Python
    scripts from the command line, never from an IDE. So that may be an issue
    too...
    --
    - Eric Brunel <eric.brunel at pragmadev.com> -
    PragmaDev : Real Time Software Development Tools - http://www.pragmadev.com

    --
    http://mail.python.org/mailman/listinfo/python-list
  • Furliz at Aug 7, 2003 at 8:11 am

    I did try self.frame.destroy as the function
    self.frame.destroy(), but the Quit button still didn't work. The
    application can be closed via the window corner X, but I'm still
    puzzled as to why it does not respond to Quit.

    Any more suggestions?
    why don't use 'sys.exit(0)' as command?
    Ex:
    quitButton = Button(root,text="Quit",command=sys.exit(0))
  • Eric Brunel at Aug 7, 2003 at 9:15 am

    furliz wrote:
    I did try self.frame.destroy as the function self.frame.destroy(),
    but the Quit button still didn't work. The
    application can be closed via the window corner X, but I'm still
    puzzled as to why it does not respond to Quit.

    Any more suggestions?

    why don't use 'sys.exit(0)' as command?
    Ex:
    quitButton = Button(root,text="Quit",command=sys.exit(0))
    Don't do that!! Written like above, sys.exit(0) will be called when the button
    is *created*, not when it is pressed! If you want to do that, write:

    quitButton = Button(root, text='Quit', command=lambda: sys.exit(0))
    --
    - Eric Brunel <eric.brunel at pragmadev.com> -
    PragmaDev : Real Time Software Development Tools - http://www.pragmadev.com
  • Sismex01 at Aug 6, 2003 at 5:22 pm
    sys.exit(x) kills the Python interpreter.

    Tkinter runs under the python interpreter.

    HTH.

    -gustavoAdvertencia:La informacion contenida en este mensaje es confidencial
    y restringida, por lo tanto esta destinada unicamente para el uso de la
    persona arriba indicada, se le notifica que esta prohibida la difusion de
    este mensaje. Si ha recibido este mensaje por error, o si hay problemas en
    la transmision, favor de comunicarse con el remitente. Gracias.
  • Andrew Gregory at Aug 7, 2003 at 9:18 am
    "Mark Daley" <mark at diversiform.com> wrote in message news:<mailman.1060190417.25846.python-list at python.org>...
    I have problems with sys.exit() when I'm running under IDLE, since it seems
    to cause ALL mainloops to exit, killing IDLE. I can't really give a whole
    lot of detail on this, since I tend to use the command line to launch my
    GUIs, anyway.
    Using tkinter seems to require a bit of lateral thinking at times (and
    I think I must have failed the test!!!). I suppose the difficulty lies
    in getting the right structure (generally true of OOP). Anyway, I did
    fix the problem and working code is given below. In effect, root does
    have to be destroyed.


    Andrew.


    # Demonstration TK interface Windows application
    # Runs ok from within IDLE
    #
    # A. Gregory, 4th August 2003
    #
    from Tkinter import *


    class CommonStuff: # to get common access to variables and functions
    def __init__(self, master):
    self.master=master
    self.frame = Frame(master)
    self.frame.bind("<Destroy>",self.CleanUp)

    def say_hi(self):
    print "Hello all"

    def myquit(self):
    self.master.destroy()

    def CleanUp(self, event):
    print "Cleaning up after Tk windows closed"


    class MyWidgets(Frame, CommonStuff):
    def __init__(self, CS):
    Frame.__init__(self, CS.frame)
    quitbutton = Button(self, text='Quit', fg='red',
    command=CS.myquit)
    quitbutton.pack(side=LEFT)
    self.hi_there = Button(self, text="Hello", command=CS.say_hi)
    self.hi_there.pack(side=LEFT)


    class Application:
    def __init__(self, CS):
    displayedwidget=MyWidgets(CS)
    displayedwidget.grid(row=0, column=0)
    CS.frame.grid(row=0, column=0)
    CS.frame.columnconfigure(0)
    CS.frame.update()



    root = Tk()
    CS = CommonStuff(root)
    mainWin = Application(CS)

    # If running from IDLE in Python 2.2 or earlier must use
    root.wait_window(CS.frame)

    # Otherwise can use
    # root.mainloop()
  • Klappnase at Aug 7, 2003 at 2:11 pm
    "Mark Daley" <mark at diversiform.com> wrote in message news:<mailman.1060190417.25846.python-list at python.org>...
    I have problems with sys.exit() when I'm running under IDLE, since it seems
    to cause ALL mainloops to exit, killing IDLE. I can't really give a whole
    lot of detail on this, since I tend to use the command line to launch my
    GUIs, anyway.
    sys.exit()will stop (exit) the python interpreter. If you are running
    your program from within IDLE it will exit IDLE, too, because IDLE
    runs in the interpreter as well.
    If you run your program from the command line sys.exit() will exit the
    interpreter and stop the program, of course any instructions in the
    code after sys.exit() won't be executed.
    I think normally that is exactly what I want in a gui program - stop
    everything if the main window is closed.
    widget.destroy() will destroy "widget" and if "widget" is the main
    window of your application it will be destroyed - and all it's
    children with it.
    That's the way it should work if you are running from within the
    interpreter:
    your application is stopped but the interpreter won't be affected by
    this.
    widget.quit() exits the mainloop and therefore destroys the main
    window but it will not exit the interpreter, so there may be other
    processes in your code still be executed after the main window is
    closed. If all processes in the interpreter are finished the
    interpreter will exit anyway, so this will work as well as sys.exit().
    However, if you run your program from the interpreter this will not
    work, because you do not call a mainloop there.

    Cheers

    Michael
  • Alex Martelli at Aug 7, 2003 at 2:28 pm

    klappnase wrote:

    "Mark Daley" <mark at diversiform.com> wrote in message
    news:<mailman.1060190417.25846.python-list at python.org>...
    I have problems with sys.exit() when I'm running under IDLE, since it
    seems
    to cause ALL mainloops to exit, killing IDLE. I can't really give a
    whole lot of detail on this, since I tend to use the command line to
    launch my GUIs, anyway.
    sys.exit()will stop (exit) the python interpreter. If you are running
    your program from within IDLE it will exit IDLE, too, because IDLE
    runs in the interpreter as well.
    Depends on what release of IDLE you're running...:
    Python 2.3+ (#1, Aug 5 2003, 17:15:06)
    [GCC 3.2.2 (Mandrake Linux 9.1 3.2.2-3mdk)] on linux2
    Type "copyright", "credits" or "license()" for more information.

    ****************************************************************
    Personal firewall software may warn about the connection IDLE
    makes to its subprocess using this computer's internal loopback
    interface. This connection is not visible on any external
    interface and no data is sent to or received from the Internet.
    ****************************************************************

    IDLE 1.0
    import sys
    sys.exit(23)
    Traceback (most recent call last):
    File "<pyshell#1>", line 1, in -toplevel-
    sys.exit(23)
    SystemExit: 23
    As you see, with the IDLE 1.0 which comes with Python 2.3, the
    exception raised by sys.exit is captured and displayed as such
    [and similarly if sys.exit is called from a module run within
    the IDLE session, rather than directly at the IDLE prompt].

    (Why KNode only lets me "Paste as Quotation", not plain "Paste", what
    I have "Select All" / "Copy" - ed from IDLE's PythonShell window,
    is one of those mysteries which may need Poirot to unravel... mah...!).
    If you run your program from the command line sys.exit() will exit the
    interpreter and stop the program, of course any instructions in the
    code after sys.exit() won't be executed.
    I think normally that is exactly what I want in a gui program - stop
    everything if the main window is closed.
    Often one may want to do some kind of clean-up at that point, but you
    may achieve that with a try/finally around the mainloop call (putting
    the cleanup code in the finally clause, of course).
    widget.destroy() will destroy "widget" and if "widget" is the main
    window of your application it will be destroyed - and all it's
    children with it.
    That's the way it should work if you are running from within the
    interpreter:
    your application is stopped but the interpreter won't be affected by
    this.
    IDLE 1.0 agrees with you. However, the interactive text-mode Python
    shell disagrees (it doesn't capture SystemExit and does terminate).



    Alex
  • Klappnase at Aug 8, 2003 at 10:52 am
    Alex Martelli <aleax at aleax.it> wrote in message news:<dmtYa.28539$an6.1003165 at news1.tin.it>...


    IDLE 1.0
    import sys
    sys.exit(23)
    Traceback (most recent call last):
    File "<pyshell#1>", line 1, in -toplevel-
    sys.exit(23)
    SystemExit: 23
    As you see, with the IDLE 1.0 which comes with Python 2.3, the
    exception raised by sys.exit is captured and displayed as such
    [and similarly if sys.exit is called from a module run within
    the IDLE session, rather than directly at the IDLE prompt].
    Oh, that is interesting, my IDLE (python-2.2.2) exits on this.
    Does this happen with sys.exit(0) too?


    Often one may want to do some kind of clean-up at that point, but you
    may achieve that with a try/finally around the mainloop call (putting
    the cleanup code in the finally clause, of course).
    Seems like you mean something like:

    def quitcmd():
    mainwindow.quit()
    do_this()
    do_that()

    If this is what you meant, what is the problem with:

    def exitcmd():
    do_this()
    do_that()
    sys.exit(0)

    I do not think that there is much difference in the behavior of these.
    May be if I launched the application from a menu and the do_that()
    function does something really stupid that causes an endless loop, I
    think with quitcmd() it might occur that the window is closed and I
    think "Fine, the application is shut down" but the buggy do_that() is
    still running in the background. With exitcmd() this won't happen, the
    window will not close before do_that() comes to an end, so I will see
    that there is something wrong.

    Best regards

    Michael
  • Alex Martelli at Aug 8, 2003 at 12:25 pm
    klappnase wrote:
    ...
    IDLE 1.0
    import sys
    sys.exit(23)
    Traceback (most recent call last):
    File "<pyshell#1>", line 1, in -toplevel-
    sys.exit(23)
    SystemExit: 23
    As you see, with the IDLE 1.0 which comes with Python 2.3, the
    exception raised by sys.exit is captured and displayed as such
    [and similarly if sys.exit is called from a module run within
    the IDLE session, rather than directly at the IDLE prompt].
    Oh, that is interesting, my IDLE (python-2.2.2) exits on this.
    One of the several good reasons to upgrade to 2.3, yes.
    Does this happen with sys.exit(0) too?
    Sure.

    Often one may want to do some kind of clean-up at that point, but you
    may achieve that with a try/finally around the mainloop call (putting
    the cleanup code in the finally clause, of course).
    Seems like you mean something like:

    def quitcmd():
    mainwindow.quit()
    do_this()
    do_that()
    Nope. There's no reason to have to bundle the cleanup as sub-functions
    inside another function and so on. Rather, the concept is that cleanup
    is generally best done at the same level in which (e.g.) a resource is
    acquired. The try/finally-free approach would be structured like:


    channel = channels_library.open_channel('blah', 'blah')

    # here: set up the GUI; then:

    mainwindow.mainloop() # start and run the GUI

    # when the GUI is done (and exits with quit) we can do our cleanup

    channel.flush_any_unsent_data() # initiate lenghty flush operation
    channel.wait_up_to(10.0) # may take up to 10 seconds' wait here
    channel.final_close() # and then we finally give up


    This only works if the mainloop exits without exiting the whole
    Python session, of course. If you want to ensure the flushing &c
    happen in any case, including uncaught exceptions, then a more
    solid structure, as I mentioned, is try/finally:

    try:
    mainwindow.mainloop()
    finally:
    channel.flush... &c &c

    If this is what you meant, what is the problem with:

    def exitcmd():
    do_this()
    do_that()
    sys.exit(0)
    Hard to say without knowing what do_this and do_that do, but in
    general (unless you have full control on them and can guarantee
    they're done very VERY fast) this is a disaster -- the GUI freezes
    (for up to 10 seconds, or a minute, or... who can tell?) while
    the program performs its potentially-lengthy cleanup operations.

    When you do background clean-up operations AFTER terminating the
    GUI, this is generally quite preferable. A clean-up operation
    can be considered a "background" one if you're not going to give
    the user feedback about what happens in it (you may e.g. log info
    to a logfile, but aren't going to popup a message box or the like).
    Of course, this doesn't matter if all cleanup operations can be
    guaranteed to terminate within, say, a couple of seconds, but
    e.g. when the ner is involved, that is quite rarely true.

    Since there are no advantages in doing background clean-up while
    still not closing the GUI, but there may be disadvantages, it
    is best to choose the approach that never gives problems -- do
    the background clean-up after closing the GUI.

    I do not think that there is much difference in the behavior of these.
    You may not have thought the issue through, then; for example, you
    may never have needed to perform length background clean-ups.
    May be if I launched the application from a menu and the do_that()
    function does something really stupid that causes an endless loop, I
    think with quitcmd() it might occur that the window is closed and I
    think "Fine, the application is shut down" but the buggy do_that() is
    still running in the background. With exitcmd() this won't happen, the
    window will not close before do_that() comes to an end, so I will see
    that there is something wrong.
    But taking many seconds to finish handshaking with communication
    partners, and other such background clean-up operations, does not
    mean "there is something wrong" -- such delays can be perfectly
    normal, yet there is no reason to keep the user staring at a frozen
    GUI while the delays go on.


    Alex

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedAug 1, '03 at 8:48a
activeAug 8, '03 at 12:25p
posts17
users8
websitepython.org

People

Translate

site design / logo © 2022 Grokbase