[IPython-dev] Interactive wx/pylab with no threads (PyOS_InputHook)

Brian Granger ellisonbg.net at gmail.com
Sun Feb 8 19:08:31 EST 2009

IPython and matplotlib devs,

Over the weekend I have been playing around to see if it is possible
to do interactive GUI work with wx from IPython *without using
threads*.  The idea here is to use PyOS_InputHook.  Currently, recent
versions of PyQt4 and PyGTK do this and if we can get wx working, we
can probably get rid of IPython's subtle threaded shells that
currently allow interactive GUIs to work.

I am attaching a Cython module that mostly works.  Here is a simple
example that works in IPython (without the -wthread option!)

In [1]: import pyximport

In [2]: pyximport.install()

In [3]: import inputhook

In [4]: inputhook.set_input_hook()

In [5]: import wx

In [6]: app = wx.PySimpleApp()

In [7]: app.MainLoop()

In [8]: f = wx.Frame(None,-1,"Look mom, no threads!")

In [9]: f.Show()
Out[9]: True

The docstring of the module also has a matplotlib example.  This
really does work and I am pretty sure it will also work in plain
vanilla python as well.  There are a few issues to work out:

* When frame are closed by clicking the red button or the "X", the
Windows don't close.  In addition, in matplotlib, this causes further

* In the current matplotlib backend wx.Yield() is called in a way that
is not safe as far as protecting against recursive calls to Yield.  I
think it should be called in this way:

app = wx.GetApp()
if app is not None:

* I don't think that interupts work yet, but I haven't tested this
thoroughly yet.

I don't have any more time to work on this right now, but I at least
wanted to share my findings with both IPython and matplotlib devs.  It
would be great if someone familiar with wx could try to figure out the
remaining issues.  If there are no takers here, I might eventually see
if wxpython itself is interested in this code (that is probably where
it really belongs anyway).


-------------- next part --------------
#include <Python.h>

static PyThreadState *event_tstate = NULL;

static void set_input_hook_c(int (*f)(void))
    event_tstate = PyThreadState_Get();
    PyOS_InputHook = f;

static void clear_input_hook_c(void)
    PyOS_InputHook = NULL;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: inputhook.pyx
Type: application/octet-stream
Size: 2384 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/ipython-dev/attachments/20090208/d35533f8/attachment.obj>

More information about the IPython-dev mailing list