[Python-Dev] Event loops, PyOS_InputHook, and Tkinter

Fredrik Lundh fredrik at pythonware.com
Mon Nov 14 23:27:28 CET 2005

Noam Raphael wrote:

> It didn't. Strange freezes started to appear, only when working from
> IDLE. This made me investigate a bit, and I've found that Tkinter
> isn't run from a seperate thread - the dooneevent() function is called
> repeatedly by PyOS_InputHook while the interpreter is idle.


The standard myreadline implementation only calls the hook *once* for
each line it reads from stdin:

    if (PyOS_InputHook != NULL)
    errno = 0;
    p = fgets(buf, len, fp);
    if (p != NULL)
        return 0; /* No error */

which isn't enough to keep any event pump going...

If you want any other behaviour, you need GNU readline, or a GUI toolkit
that takes control over the InputHook, just like Tkinter.  And that won't
help you if you want portable code; for example, Tkinter on Windows only
keeps the event pump running as long as the user doesn't type anything.
As soon as the user touches the keyboard, the pump stops.

To see this in action, try this:

    >>> from Tkinter import *
    >>> label = Label(text="hello")
    >>> label.pack()

and then type

    >>> label.after(1000, lambda: label.config(bg="red"))

and press return.  The widget updates after a second.

Next, type

    >>> label.after(1000, lambda: label.config(bg="blue"))

press return, and immediately press space.  This time, nothing happens,
until you press return again.

If you want to write portable code that keeps things running "in the
background" while the users hack away at the standard interactive
prompt, InputHook won't help you.


More information about the Python-Dev mailing list