You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee='https://github.com/asvetlov'closed_at=<Date2012-03-26.19:16:00.533>created_at=<Date2004-07-12.20:16:30.000>labels= ['expert-IDLE', 'type-feature', 'expert-tkinter']
title='Support using Tk without a mainloop'updated_at=<Date2012-03-26.19:16:15.538>user='https://bugs.python.org/noamr'
In the regular python shell, you can open Tk windows,
and they will operate even though you didn't call
Tkinter.mainloop(). This is useful, for example, when
you manipulate matplotlib graphs from within the python
shell.
This is done by a hook, installed when a tkapp object
is being initialized, which handles Tk events while the
shell is waiting for user input.
I imitated this behaviour in IDLE: When the subprocess
is idle, it checks whether Tkinter._default_root is set
(this happens when the Tkinter.Tk class, which makes a
tkapp object, is initialized, unless
Tkinter._use_default_root is False), and if so, handles
Tk events.
Can you give me some more information on the hook in the
Python interpreter? Where is it in the code?
noamr commented on Jan 30, 2005
noamrmannequin
MannequinAuthor
More actions
Logged In: YES
user_id=679426
in _tkinter.c, look for EventHook - you'll find the
EventHook function, which is called when the interpreter is
idle, and the Enable/Disable EventHook functions.
In readline.c, line 765, you'll find the call to
PyOS_InputHook, when waiting for input.
Perhaps a more general approach would be to let Python code
call PyOS_InputHook, for example, by defining
readline.call_input_hook() and readline.has_input_hook().
Then IDLE would be able to call them when idle, with no
Tkinter-specific code.
I'd lost track of it because it got switched to tkinter.
mdehoon commented on Feb 4, 2005
mdehoonmannequin
Mannequin
More actions
Logged In: YES
user_id=488897
I agree, this is basically the same bug as bpo-798058. The call
to readline.call_input_hook sounds like a good solution. But
the hook function should be different than the current
EventHook in _tkinter.c. That hook function sits in a loop
until a keyboard event is noticed. A problem occurs if there
is more than one hook function. Currently, that is not
possible in Python, since there is only one PyOS_InputHook.
I am working on a patch in which PyOS_InputHook is replaced
by PyOS_AddInputHook and PyOS_RemoveInputHook, so that there
can be more than one hook functions.
Now suppose that there is one hook function to handle Tk
events, and another one e.g. handling messages to windows in
Microsoft Windows. (This is a real issue for one of my
extension modules). If python sits in a loop in _tkinter.c's
EventHook until a key is pressed, the MS windows won't get
their messages.
Currently, the EventHook function sits in a loop handling
Tcl events until keyboard input is detected. The presence of
Tcl events is checked every Tkinter_busywaitinterval
milliseconds. If a Tcl event arrives during this interval,
it won't be handled until the end of the interval. However,
with the default value of Tkinter_busywaitinterval = 20
milliseconds, that delay is not noticable.
Now consider the situation in which there can be more than
one input hook, for example set by different extension
modules. We cannot have EventHook sit in a loop until
keyboard input is detected, because that would prevent other
PyOS_InputHooks from being serviced. So in the EventHook in
the patch, the function returns immediately after handling
all Tcl events.
If we use Python from the command line and open a Tkinter label:
>>> from Tkinter import*
>>> l = Label()
then readline will call PyOS_InputHook ten times per second
while Python is idle. Because PyOS_InputHook points to
EventHook, we will return to the EventHook function almost
immediately. Effectively, we are then in the same situation
as before the patch. On Cygwin, however, previously mainloop
needed to be run in order for the label to appear; this is
no longer necessary with this patch. On Windows, currently
PyOS_InputHook is partially broken, as it is called only
once per command instead of ten times per second. This patch
fixed that also (same as patch python/issues-test-cpython#1049855).
If we have two or more input hooks, they are called
successively by readline. Since each input hook returns
after it has no more work to do, all of the input hooks are
guaranteed to be serviced.
To be able to have more than one input hook, we need to
replace PyOS_InputHook by three functions:
PyOS_AddInputHook, PyOS_RemoveInputHook, and
PyOS_CallInputHooks. For the third function, the
corresponding Python function call_input_hooks was created
in the readline module.
By adding a call to readline.call_input_hooks in run.py, as
suggested by Noam, all input hook functions are serviced
when IDLE is idle. So we can use Tkinter without calling
mainloop, and we can use other extension packages that use
input hooks. We can even do both:
>>> import Tkinter
>>> import gist # my extension module also needs input hooks
>>> Tkinter.Label() # label appears
>>> gist.window() # Graphics window appears.
works both with command-line python and IDLE.
I'm interested to hear your comments and suggestions. If
this patch seems like the way to go, I'd be happy to write
the documentation for it.
Noam, Michiel, what is the current position
on this patch? There have been a lot of related
patches and much discussion on python-dev.
noamr commented on Nov 23, 2005
noamrmannequin
MannequinAuthor
More actions
Logged In: YES
user_id=679426
It seems to me that the python-dev discussion didn't reach a
conclusion. My patch is a sort of a workaround that lets you
use Tk interactively from IDLE - it doesn't really invoke
PyOS_InputHook. Since Tk always sets itself as
PyOS_InputHook, it solves the Tk problem, which I think is
the most common one.
A more "correct" approach, which can be easily implemented,
is to give a Python API that will call PyOS_InputHook. This
would enable IDLE to imitate the exact behaviour of the
textual interactive interpreter. It would have to be written
in C, of course, and the question is where to put that C
function: should it be in a C module which comes with IDLE,
like the old "interrupt" module, or should a function be
added to the "sys" or "os" modules?
There's a subtle bug in the currently applied patch.
importtkintera=tkinter.Tk()
b=tkinter.Tk()
Closing the first window will prevent closing the second window. This example may seem abstract, but it is a real issue especially when using matplotlib with multiple figures.
Attached is a patch that incorporates what IdleX uses for driving the Tk/Tcl event loop.
Activity
noamr commentedon Jul 12, 2004
In the regular python shell, you can open Tk windows,
and they will operate even though you didn't call
Tkinter.mainloop(). This is useful, for example, when
you manipulate matplotlib graphs from within the python
shell.
This is done by a hook, installed when a tkapp object
is being initialized, which handles Tk events while the
shell is waiting for user input.
I imitated this behaviour in IDLE: When the subprocess
is idle, it checks whether Tkinter._default_root is set
(this happens when the Tkinter.Tk class, which makes a
tkapp object, is initialized, unless
Tkinter._use_default_root is False), and if so, handles
Tk events.
For me it works very well.
Have a good day,
Noam Raphael
kbkaiser commentedon Jul 14, 2004
Logged In: YES
user_id=149084
Can you give me some more information on the hook in the
Python interpreter? Where is it in the code?
noamr commentedon Jan 30, 2005
Logged In: YES
user_id=679426
in _tkinter.c, look for EventHook - you'll find the
EventHook function, which is called when the interpreter is
idle, and the Enable/Disable EventHook functions.
In readline.c, line 765, you'll find the call to
PyOS_InputHook, when waiting for input.
Perhaps a more general approach would be to let Python code
call PyOS_InputHook, for example, by defining
readline.call_input_hook() and readline.has_input_hook().
Then IDLE would be able to call them when idle, with no
Tkinter-specific code.
kbkaiser commentedon Feb 4, 2005
Logged In: YES
user_id=149084
Hm, this seems closely related to Bug 798058
I'd lost track of it because it got switched to tkinter.
mdehoon commentedon Feb 4, 2005
Logged In: YES
user_id=488897
I agree, this is basically the same bug as bpo-798058. The call
to readline.call_input_hook sounds like a good solution. But
the hook function should be different than the current
EventHook in _tkinter.c. That hook function sits in a loop
until a keyboard event is noticed. A problem occurs if there
is more than one hook function. Currently, that is not
possible in Python, since there is only one PyOS_InputHook.
I am working on a patch in which PyOS_InputHook is replaced
by PyOS_AddInputHook and PyOS_RemoveInputHook, so that there
can be more than one hook functions.
Now suppose that there is one hook function to handle Tk
events, and another one e.g. handling messages to windows in
Microsoft Windows. (This is a real issue for one of my
extension modules). If python sits in a loop in _tkinter.c's
EventHook until a key is pressed, the MS windows won't get
their messages.
The following structure might work better:
Obviously I need to do some more thinking about this.
mdehoon commentedon Feb 8, 2005
Logged In: YES
user_id=488897
I have written a patch that solves this problem more
generally via PyOS_InputHook, as suggested by Noam. This
patch also solves the related bugs bpo-1053687, bpo-798058, and
supersedes patch bpo-1049855. The patch is available at
http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/inputhooks.diff
Currently, the EventHook function sits in a loop handling
Tcl events until keyboard input is detected. The presence of
Tcl events is checked every Tkinter_busywaitinterval
milliseconds. If a Tcl event arrives during this interval,
it won't be handled until the end of the interval. However,
with the default value of Tkinter_busywaitinterval = 20
milliseconds, that delay is not noticable.
Now consider the situation in which there can be more than
one input hook, for example set by different extension
modules. We cannot have EventHook sit in a loop until
keyboard input is detected, because that would prevent other
PyOS_InputHooks from being serviced. So in the EventHook in
the patch, the function returns immediately after handling
all Tcl events.
If we have two or more input hooks, they are called
successively by readline. Since each input hook returns
after it has no more work to do, all of the input hooks are
guaranteed to be serviced.
To be able to have more than one input hook, we need to
replace PyOS_InputHook by three functions:
PyOS_AddInputHook, PyOS_RemoveInputHook, and
PyOS_CallInputHooks. For the third function, the
corresponding Python function call_input_hooks was created
in the readline module.
I'm interested to hear your comments and suggestions. If
this patch seems like the way to go, I'd be happy to write
the documentation for it.
mdehoon commentedon Feb 12, 2005
Logged In: YES
user_id=488897
Richard Madden was kind enough to test the patch at
http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/inputhooks.diff.
This led to the discovery of two bugs in my patch and one
preexisting bug in Tkinter.py. For this second bug, I
submitted a separate patch (bpo-1121234). I uploaded a fixed
patch at
http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/inputhooks.diff;
together with patch bpo-1121234 the input hooks appear to be
working correctly.
dickmadden commentedon Feb 14, 2005
Logged In: YES
user_id=1219007
I've tried the updated patches with Tkinter and my rasmol
extension using the new inputhooks scheme and everything
seems to be coexisting just fine.
mdehoon commentedon Mar 3, 2005
Logged In: YES
user_id=488897
Patch bpo-1121234 (see my previous comment) was accepted and is
now included in CVS, clearing the way for this patch.
kbkaiser commentedon Nov 23, 2005
Logged In: YES
user_id=149084
Noam, Michiel, what is the current position
on this patch? There have been a lot of related
patches and much discussion on python-dev.
noamr commentedon Nov 23, 2005
Logged In: YES
user_id=679426
It seems to me that the python-dev discussion didn't reach a
conclusion. My patch is a sort of a workaround that lets you
use Tk interactively from IDLE - it doesn't really invoke
PyOS_InputHook. Since Tk always sets itself as
PyOS_InputHook, it solves the Tk problem, which I think is
the most common one.
A more "correct" approach, which can be easily implemented,
is to give a Python API that will call PyOS_InputHook. This
would enable IDLE to imitate the exact behaviour of the
textual interactive interpreter. It would have to be written
in C, of course, and the question is where to put that C
function: should it be in a C module which comes with IDLE,
like the old "interrupt" module, or should a function be
added to the "sys" or "os" modules?
12 remaining items
asvetlov commentedon Mar 14, 2012
The issue is fixed. Thanks to Guilherme Polo.
serwy commentedon Mar 26, 2012
There's a subtle bug in the currently applied patch.
Closing the first window will prevent closing the second window. This example may seem abstract, but it is a real issue especially when using matplotlib with multiple figures.
Attached is a patch that incorporates what IdleX uses for driving the Tk/Tcl event loop.
python-dev commentedon Mar 26, 2012
New changeset 837ac3abf0c5 by Andrew Svetlov in branch 'default':
Issue bpo-989712: update the code to process tkinter messages in IDLE
http://hg.python.org/cpython/rev/837ac3abf0c5
asvetlov commentedon Mar 26, 2012
Roger, your patch is pushed.
Please next time when you reopen closed bug set 'Resolution' field to 'remind'.
Thank you.