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