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

Michiel Jan Laurens de Hoon mdehoon at c2b2.columbia.edu
Thu Nov 10 18:16:36 CET 2005


Martin v. Löwis wrote:

> Michiel Jan Laurens de Hoon wrote:
>
>> It's not because it likes to be in charge, it's because there's no 
>> other way to do it in Python.
>
> As I said: this is simply not true.

You are right in the sense it is possible to get events handled using 
the solutions you proposed before (sorry for not responding to those 
earlier). But I don't believe that these are very good solutions:

> You are missing multi-threading, which is the widely used
> approach to doing things simultaneously in a single process. In one
> thread, user interaction can occur; in another, computation. If you need
> non-blocking interaction between the threads, use queues, or other
> global variables. If you have other event sources, deal with them
> in separate threads.

The problem with threading (apart from potential portability problems) 
is that Python doesn't let us know when it's idle. This would cause 
excessive repainting (I can give you an explicit example if you're 
interested).

But there is another solution with threads: Can we let Tkinter run in a 
separate thread instead?

> Yes, it is possible to get event loops with Tkinter. Atleast on Unix,
> you can install a file handler into the Tk event loop (through
> createfilehandler), which gives you callbacks whenever there is some
> activity on the files.

This works, but only if Tkinter is installed, and even then it will give 
poor performance due to the busy-loop with 20 ms sleep in between in 
Tkinter. Furthermore, this will not work with IDLE, because the Python 
thread that handles user commands never enters the Tkinter event loop, 
even if we import Tkinter. AFAIK, there is no easy solution to this.

> Furthermore, it is possible to turn the event loop around, by doing
> dooneevent explicitly. 

Here, the problem is that we don't know *when* to call dooneevent, so 
we'd have to do a busy-loop and sleep in between.

>> Tkinter is a special case among GUI toolkits because it is married to 
>> Tcl. It doesn't just need to handle its GUI events, it also needs to 
>> run the Tcl interpreter in between. 
>
> That statement is somewhat deceiving: there isn't much interpreter to
> run, really.

I may be wrong here, but I'd think that it would be dangerous to run 
Tkinter's event loop when one thread is waiting for another (as happens 
in IDLE).

>> Which is why Tkinter needs to be in charge of the event loop. For 
>> other GUI toolkits, I don't see a reason why they'd need their own 
>> event loop.
>
> They need to fetch events from the operating system level, and dispatch
> them to the widgets. 

This is a perfect task for an event loop located in Python, instead of 
in an extension module. I could write a prototype event loop for Python 
to demonstrate how this would work.

Sorry if I'm sounding negative, but we've actually considered many 
different things to get the event loop working for our scientific 
visualization software, and we were never able to come up with a 
satisfactory scheme within the current Python framework. Other packages 
have run into the same problem (e.g. matplotlib, which now recommends 
using the interactive ipython instead of regular python; the python 
extension for the Rasmol protein viewer is another).

--Michiel.

-- 
Michiel de Hoon
Center for Computational Biology and Bioinformatics
Columbia University
1150 St Nicholas Avenue
New York, NY 10032




More information about the Python-Dev mailing list