recipe: Pyglet in a background thread

512 views
Skip to first unread message

Zachrahan

unread,
Apr 28, 2008, 2:42:04 PM4/28/08
to pyglet-users
Hello all,

I've recently worked out (more or less...) a pretty nice way of
running the pyglet event loop in a separate thread while allowing you
to safely interact with pyglet windows, etc., from other threads. The
primary usage pattern that interests me here is running the event loop
as a background thread during an interactive python session (e.g. for
image viewing or plotting or some such); however others might have
different uses, like having the main thread handle network requests or
something.

The general approach is to run a modified pyglet event loop in a
background thread, and have this event loop periodically check a
message queue for "messages" (python functions to call). I also wrote
helper functions for putting events into the queue and retrieving the
results, and easier yet, a class that proxies an object constructed by
the background thread, funneling method calls and attribute setting
through the message queue transparently.

I hacked up the opengl.py demo class to work as a background window to
provide an example of usage:
>>> import background_pyglet
>>> import background_opengl
>>> window = background_pyglet.PygletProxy(background_opengl.GLWindow, resizable=True)
>>> window.set_color(1,0,1,1)
>>> window.speed = 0.5
>>> window.close()

Now, there are a few caveats. I found that to ensure that the queue
gets checked regularly, one wants pyglet the event loop to run
frequently -- but the default pyglet event loop forcibly redraws every
window at every cycle, and too-frequent re-draws hog the processor. I
found that by making the event loop *not* call switch_to(), on_draw()
and flip() on every window at every iteration, the message queue can
be checked rapidly without forcing unnecessary window redraws. This
means that event handlers (and other functions) that change window
state must call on_draw() on the relevant windows, and that each
window's on_draw method must call switch_to() first and flip() last.
It's very easy to write windows that work in this way, with the added
benefit that this approach can often be more processor-efficient than
the standard pyglet event loop.

http://groups.google.com/group/pyglet-users/web/background_pyglet.zip

Hope this is useful to some,
Zach Pincus

Andrew Straw

unread,
Apr 28, 2008, 4:43:57 PM4/28/08
to pyglet...@googlegroups.com
Thanks Zach, this looks useful, though I haven't had time to try it or
examine it in any detail.

One note -- IPython has collected a number of such solutions for wx,
GTK, and so on, and I'd be willing to bet they'd include a solution for
interactive work with IPython and pyglet. (IIRC, these are started with
the command line argument when invoking ipython "-wthread" for wx.)

-Andrew

Colin Bean

unread,
Apr 30, 2008, 11:03:01 PM4/30/08
to pyglet...@googlegroups.com
Thanks for the code, Zach! I adapted your idle function to
periodically poll for midi input, and so far so good. Before I was
schedule()ing my polling function, and drawing way more than
necessary (doh). I've gotten a much better understanding of how
pyglet's event loop works and how to customize that (and still don't
have to write my own event loop -- cool!)

Colin

Reply all
Reply to author
Forward
0 new messages