[Tutor] Can I ask if Tkinter.mainloop() is running?

Danny Yoo dyoo@hkn.eecs.berkeley.edu
Mon, 22 Jul 2002 15:05:20 -0700 (PDT)


On Mon, 22 Jul 2002, Gregor Lingl wrote:

> It's possible (and sometimes convenient) to develop Tkinter-programs
> interactively with IDLE provided one doesn't write the mainloop() call
> into the program file. Of course one can add this later if one wants to
> run the program standalone.
>
> I'd like to know if - and how - it were possible to use some test if a
> Tkinter.mainloop (in this case the one of IDLE) is already running, thus
> having a statement similar to
>
> if __name__ == '__main__':
>      < stuff>
>
> at the end of the program of the form:
>
> if not <mainloop already active>:
>     app.mainloop()


Yes, this is possible if we intentionally raise an exception, or use the
convenient 'traceback' module.


When an exception is raised to us, it gives us information about the 'call
stack', that is, it tells us which functions were running right before the
exception was raised.  Although we often use 'traceback' as a debugging
tool, we can abuse this a bit to help us write a mainloop() detector.


Here's what a call stack looks like, just to get a feel for what we're
about to try:

###
>>> def foo(): return bar()
...
>>> def bar(): return traceback.extract_stack()
...
>>> foo()
[('<stdin>', 1, '?', None), ('<stdin>', 1, 'foo', None), ('<stdin>', 1,
'bar', None)]
>>> bar()
[('<stdin>', 1, '?', None), ('<stdin>', 1, 'bar', None)]
###

The '?' at the very bottom of the call stack represents the interpreter.
(Forgive me for using 'foo' and 'bar' as names.)


So we can detect if we've been called while within Tkinter's mainloop by
examining the call stack.  I did some experimentation, and came up with
this:

###
def getTkinterLocation():
    """Returns the location of the Tkinter module."""
    import Tkinter
    if Tkinter.__file__.endswith('pyc'):
        return Tkinter.__file__[:-1]
    return Tkinter.__file__


def inTkinterMainloop():
    """Returns true if we're called in the context of Tkinter's
mainloop(), and false otherwise."""
    stack = traceback.extract_stack()
    tkinter_file = getTkinterLocation()
    for (file_name, lineno, function_name, text) in stack:
        if (file_name, function_name) == (tkinter_file, 'mainloop'):
            return 1
    return 0
###



With recent developments in IDLEfork (the development version of IDLE),
though, you shouldn't need to do this check because Tkinter programs
should work cleanly in IDLE now.


You may want try the IDLEfork version of IDLE and see if this has been
fixed already:

    http://idlefork.sourceforge.net/




> QUESTION 2:
> ===========
>
> Is there a special mailing list or something similar
> dedicated to Tkinter related stuff?

Hmmm!  I don't know about this one.  Does anyone else know?