Registering Event Handlers in Pyglet
The Problem and Pyglet’s own solutions
Pyglet’s documentation suggests a number of methods to receive events.
The recommended method of using @ decorators works for global methods where the event object is known. But if its for a class method or the event object is passed in later, this will not work.
The alternative is to simply over-write the existing handler with something like
window.on_resize = self.on_resize
Unfortunately most of them end up with the following error:
window.set_handler( window.on_key_release, self.on_key_release ) AttributeError: 'Win32Window' object has no attribute 'on_key_release'
This discussion on the developer list explains it. This method only works when the platform’s window class has an existing method to handle the event. And not all events are handled by default, so when you come across this, BOOM!
Even then, when it works this is also a double edged sword. The existing handlers are there for a reason! For example, if you over-write the on_resize method of Window your application will no longer draw (took me a while to figure this out).
So yes, Pyglet’s documentation is really, REALLY, asking for trouble.
The Proper Solution?
Use the “push_handlers” method.
Pyglet automatically detects a method with the event’s name and dispatches the event.
So we can just add methods to our class and we’ll automatically receive the events.
class Test: def attachToWindow( self, window ): window.push_handlers( self ) def on_key_press( self, symbol, modifiers ): # method name matches the 'on_key_press' event! print "Keypress"
Or we can manually specify which events we care about.
If we do this, we must specify the actual function that receives the event.
class Test: def attachToWindow( self, window ): window.push_handlers( on_key_press = self.on_key_press ) def on_key_press( self, symbol, modifiers ): # method name matches the 'on_key_press' event! print "Keypress"