Tkinter wait_variable problem: hangs at termination
Peter Otten
__peter__ at web.de
Tue Jun 8 15:45:14 EDT 2004
<veröffentlicht & per Mail versendet>
Russell E. Owen wrote:
> I want to support execution of simple user-written scripts in a Tkinter
> application. The scripts should be able to wait for data and such
> without hanging the GUI (and without having to write the script as a
> bunch of asynchronously called subroutines).
>
> I decided to use Tkinter's wait_variable. I built a "script runner"
> object that has suitable wait methods. Internally each of these methods
> registers a callback that sets a variable when the wait condition is
> satisfied, then calls wait_variable to wait until the variable is set.
>
> The resulting scripts are simple and seem to work well, e.g.:
>
> myscript(sr):
> # do some normal python stuff that is fast
> sr.waitForData(...)
> # more normal fast python stuff
> sr.waitForMS(time)
> # etc.
>
> Unfortunately, if a user closes the root window while wait_variable is
> waiting, the application never fully quits. On my unix box the root
> window closes but the command-line prompt never returns and ^C is
> ignored. The process isn't using excess cpu cycles; it's just not
> listening.
>
> I have tried registering an atexit handler and adding a __del__ method
> so that the variable being waited on is toggled at shutdown, but it
> makes no difference.
>
> Here is an example:
> <ftp://ftp.astro.washington.edu/pub/users/rowen/python/WaitBug.py>
> Press "Start" to start the script (which simply prints a number to
> sys.stdout every second, then quits. Close the root window while the
> script is waiting to print the next number, or after pausing the script,
> and you'll see the problem.
>
> Any suggestions for how to avoid/work around this problem? If it's a
> Tkinter bug I'll report it.
>
> -- Russell
>
> P.S. I saw that some perl/Tk users got around a different problem by
> faking wait_variable by running a tight "do one event, see if the wait
> condition is satisfied" loop.
>
> I don't think Tkinter allows one to execute a single event, and I
> suspect it would be inefficient even if it were possible. I might be
> able to use update (though the nice thing about wait_variable is most of
> the action happens down at the tcl/tk level, presumably making it
> maximally efficient).
>
> (This is one of those rare times I wish Tkinter worked at the C level
> the way perl's tk interface does.)
Without any deeper insight in your script - could the following meet your
needs?
# instead of atexit.register():
def dw():
self.cancel()
self._tk.destroy()
self._tk.protocol("WM_DELETE_WINDOW", dw)
and further down:
root = Tkinter.Tk()
ScriptRunner._tk = root
That way your runner would get notified if the window shall be closed.
Peter
More information about the Python-list
mailing list