Tkinter programming problem

Alex Martelli aleax at aleax.it
Fri Aug 8 08:25:15 EDT 2003


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





More information about the Python-list mailing list