[Idle-dev] Re: [Tutor] How to interrupt in IDLE (fwd)
Guido van Rossum
guido@python.org
Mon, 15 Apr 2002 08:53:53 -0400
> >Thanks. Unfortunately, there's no real easy way out of this.
> >The ^C can only be detected by Tkinter's event loop, and that isn't
> >active when the Python VM is executing code, only when it's asking for
> >input or printing output.
>
> I think that there is one easy way out of this, but really the Tkinter
> mainloop C code should be fixed to get around the 30 msec. sleep in the
> Tkinter mainloop. The sleep in the loop creates dead time,
Only 30 msec, which is plenty for responding to keyboard and mouse input.
> causes CPU burn
> because it isn't using some kind of select call,
Not measurably; during those 30 msec it's not using CPU time, and the
test it does for an event is fast. I bet you can't notice the CPU
usage at all.
> and won't process Python
> signals if it's vwait waiting in Tk.
Which is *not* the problem here. The problem is that when you've got
some kind of window (X11 or Win32 or Mac, doesn't matter), ^C doesn't
send a signal, but simply a keyboard character.
I have advocated scheduling something
> regularly on the Tcl event queue to check for Python signals, using a
> function already in _tkinter.c - Tkapp_CreateTimerHandler.
Yeah, but unfortunately nobody has been able to come up with working
code -- and the only person in the world who might be able to (Jeff
Hobbs) was lukewarm the last time this was brought up.
(Understandably since he'd be helping the "competition". :-)
> Although I think this is technically the correct way to do it, there is an
> easy route that may solve your problem: do the mainloop in Python.
>
> self.exit = -1
> while self.exit < 0:
> self.tk.dooneevent(0)
>
> where self.tk.quit() is changed to set self.exit to 0. This has no sleep,
> no dead time, reacts to Keyboard Interupt after any Tcl event (e.g. mouse
> move),
I think you misunderstand the situation completely. The ^C doesn't
get translated into a KeyboardInterrupt by self.tk.dooneevent() --
there's code in IDLE to do that -- and, in addition, the original
problem was that when the user code is executing
while 1:
pass
there's nothing looking for Tk events at all.
>and has the added advantage of being able to easily add hooks into
> the main loop to poll for other things:
>
> self.exit = -1
> while self.exit < 0:
> self.tk.dooneevent(0)
> # plug in any other polling checks here: asyncore ...
> if self.hooks is not None: map (eval, self.hooks)
>
> This seems to work well, though I haven't tested it using threads.
> To see examples of this approach, I think the CVS version of the Tix demos
> have been switched over to use this:
> http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/python/
> python/dist/src/Demo/tix/samples/SHList2.py?
> rev=1.3&content-type=text/vnd.viewcvs-markup
--Guido van Rossum (home page: http://www.python.org/~guido/)