I know you could have looked into sympy sources but here is the
ManagedWindow class from sympy plotting code, which I have modified
for pyglet 1.1 event decorators.
from
pyglet.gl import *
from pyglet.window import Window
from pyglet import app
from pyglet.clock import Clock
from threading import Thread, Lock, Event
gl_lock = Lock()
class ManagedWindow(Window):
"""
A pyglet window with an event loop which executes automatically
in a separate thread. Behavior is added by creating a subclass
which overrides setup, update, and/or draw.
"""
fps_limit = 30
default_win_args = dict(width=600,
height=500,
vsync=False,
resizable=True)
def __init__(self, **win_args):
"""
It is best not to override this function in the child
class, unless you need to take additional arguments.
Do any OpenGL initialization calls in setup().
"""
self.win_args = dict(self.default_win_args, **win_args)
self.Thread=Thread(target=self.__event_loop__)
self.Thread.start()
def __event_loop__(self, **win_args):
"""
The event loop thread function. Do not override or call
directly (it is called by __init__).
"""
gl_lock.acquire()
try:
try:
super(ManagedWindow, self).__init__(**self.win_args)
self.switch_to()
self.setup()
app.run()
except Exception, e:
print "Window initialization failed: %s" % (str(e))
finally:
gl_lock.release()
def on_key_press(self, symbol, modifiers):
pass
def on_key_release(self, symbol, modifiers):
pass
def on_mouse_scroll(self, x, y, dx, dy):
pass
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
pass
def on_resize(self, w, h):
pass
def on_close(self):
"""
Closes the window.
"""
self.close()
def setup(self):
"""
Called once before the event loop begins.
Override this method in a child class. This
is the best place to put things like OpenGL
initialization calls.
"""
pass
def on_update(self, dt):
"""
Called before draw during each iteration of
the event loop. dt is the elapsed time in
seconds since the last update. OpenGL rendering
calls are best put in draw() rather than here.
"""
pass
def on_draw(self):
"""
Called after update during each iteration of
the event loop. Put OpenGL rendering calls
here.
"""
pass
if __name__ == '__main__':
ManagedWindow()
___________________________________________________________
and, here is the plot_window.py file
from
pyglet.gl import *
from pyglet.clock import Clock
from pyglet.window.mouse import LEFT, RIGHT, MIDDLE
from managed_window import ManagedWindow
from plot_camera import PlotCamera
from plot_controller import PlotController
from time import clock
class PlotWindow(ManagedWindow):
def __init__(self, plot, **kwargs):
"""
Named Arguments
===============
antialiasing = True
True OR False
ortho = False
True OR False
invert_mouse_zoom = False
True OR False
"""
self.plot = plot
self.camera = None
self._calculating = False
self.antialiasing = kwargs.pop('antialiasing', True)
self.ortho = kwargs.pop('ortho', False)
self.invert_mouse_zoom = kwargs.pop('invert_mouse_zoom',
False)
self.linewidth = kwargs.pop('linewidth', 1.5)
self.title = kwargs.setdefault('caption', "SymPy Plot")
self.last_caption_update = 0
self.caption_update_interval = 0.2
self.drawing_first_object = True
self.clock = Clock()
super(PlotWindow, self).__init__(**kwargs)
def setup(self):
self.camera = PlotCamera(self, ortho = self.ortho)
self.controller = PlotController(self,
invert_mouse_zoom=self.invert_mouse_zoom)
self.push_handlers(self.controller)
.................... and other decorators like on_resize, on_draw
etc...
If I remember correct, there are other places, where thread lock is
used in sympy plotting. You can look into that, try creating a program
based on this and share us how it goes.
Saroj.
On Apr 9, 10:39 pm, "Colin Bean" <
ccb...@gmail.com> wrote:
> Hi Zach,
>
> I've only just started using Pyglet so I can't offer any expert
> advice, here's my 2 cents...
> I'd suspect that running Pyglet in a separate thread could be a
> problem:
http://groups.google.com/group/pyglet-users/browse_thread/thread/11f4...
> (Alex says "pyglet is completely thread-unsafe; you'll need to manage
> all locking yourself. ") I'd probably try to run the Pyglet app as
> the main thread, and the other part as a background thread.
> Better yet (especially since it might be easier to run a terminal this
> way), you could break your code into a Pyglet application which does
> the drawing, and a terminal application which handles the commands and
> communicates with the pyglet app via networking (or a FIFO). There's
> been mention of a possible Twisted-based event look for Pyglet in the
> works, which seems like it would make this sort of thing very easy.
> On the Pyglet side of things, you could poll for input from the
> terminal app, and use those to control your drawing. I recently had a
> stab at doing something like this when I got Pyglet to handle input
> from a MIDI controller. I wrote a function which polls a MIDI port
> (once), and dispatches a custom event if it reads a MIDI message.
> Then I called it every frame with pyglet.clock.schedule(). So far
> it's stable, and responsive enough (for controlling on screen drawing,
> haven't tried any audio). In your case, you could check for messages
> sent to your drawing app each frame. That said, does anyone know of a
> better way to dispatch pyglet events from realtime input like this? I
> haven't done any tests yet to see how badly calling schedule() effects
> the CPU load / performance.
>
> Hope that was somewhat helpful,
> Colin
>