Table of contents
1.
Introduction
2.
The pyglet event framework
2.1.
Setting event handlers
2.2.
Stacking event handlers
2.3.
Creating your own event dispatcher
2.4.
Implementing the Observer pattern
3.
Frequently Asked Questions 
3.1.
What is pyglet?
3.2.
How to stack event handlers in pyglet?
3.3.
How to Implement the Observer pattern?
4.
Conclusion 
Last Updated: Mar 27, 2024

The pyglet event framework

Author Tarun Singh
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

In this blog, we will discuss the pyglet event framework. But before discussing the pyglet event framework first, we need to know what pyglet is? So, pyglet is a Python library that provides an object-oriented application programming interface for developing games and other multimedia applications. Pyglet is a BSD-licensed (Berkley Software Distributionprogram that runs on Microsoft Windows, macOS, and Linux. So, now let us start with the pyglet event framework.

The pyglet event framework

A software framework is an abstraction in computer programming that allows generic software to be selectively altered by extra user-written code, resulting in application-specific software. The pyglet.window uses a uniform event pattern, pyglet.mediapyglet.apppyglet.textpyglet.input, and other modules also use uniform events. This allows you to attach event handlers to objects in various ways. By subclassing EventDispatcher, you can easily reuse this pattern in your classes.

An "event dispatcher" is an object that has events that it has to tell other objects about, and an "event handler" is a code that can be added to the dispatcher.

Setting event handlers

An event handler is a function in the pyglet event framework with a well-defined parameter list linked to the event type. The pyglet.window.Window.on resize() event contains the arguments (width, height), so an event handler may be defined as:

 

def when_resized(width, height):
    pass
You can also try this code with Online Python Compiler
Run Code

 

The Window class in the pyglet event framework is a subclass of EventDispatcher, allowing it to dispatch events independently. Event handlers can be added in a few different methods to receive events. The simplest method is to link the event handler to the object's relevant attribute. This will replace the default event handler:

 

window = pyglet.window.Window()
def on_resize(width, height):
    pass
window.on_resize = on_resize
You can also try this code with Online Python Compiler
Run Code


It may be desirable to replace the default event handler in some circumstances. The event decorator is most convenient in the most basic scenarios. However, utilizing the decorator has one drawback: you can only add one more event handler. We will see how to add multiple event handlers further in this blog. Alternatively, you can subclass the event dispatcher and add the event handler as a method to replace default event handlers:

 

class MyWindow(pyglet.window.Window):
    def when_resized(self, width, height):
        pass
You can also try this code with Online Python Compiler
Run Code

Stacking event handlers

Till now we have discussed event handlers in the pyglet event framework, it's time to discuss stacking event handlers. It's common to attach multiple event handlers to a single event. Instead of replacing event handlers, EventDispatcher lets you stack them on top of one another. The event will propagate from the top to the bottom of the stack, but any handler along the way can stop it.

Use the push_handlers() method to add an event handler to the stack:

 

def when_key_pressed(symbol, modifiers):
    if symbol == key.SPACE:
        fire_laser()
window.push_handlers(when_key_pressed)
You can also try this code with Online Python Compiler
Run Code

 

Pushing handlers rather than setting them can be helpful when dealing with different parameterizations of events in separate routines. The program preserves the usual behavior while providing new functionality by pushing the event handler rather than setting it.

Returning an actual value prevents the remaining event handlers in the stack from receiving the event. When pressed upon the window, the following event handler stops the escape key from exiting the program:

 

def when_key_pressed(symbol, modifiers):
    if symbol == key.ESCAPE:
        return True
window.push_handlers(when_key_pressed)
You can also try this code with Online Python Compiler
Run Code

 

You can simultaneously push several event handlers, which is very handy when used with the pop_handlers() function. The following example shows that specific event handlers are pushed onto the stack when the game starts. The handlers are popped off in one go when the game ends (possibly returning to a menu screen):

 

def start_game():
    def when_key_pressed(symbol, modifiers):
        print('The key pressed in game')
        return True

    def when_mouse_pressed(x, y, button, modifiers):
        print('Mouse button pressed in game')
        return True

    window.push_handlers(when_key_pressed, when_mouse_pressed)
def terminate_game():
    window.pop_handlers()
You don't get to choose which handlers to pop off the stack; instead, the entire top "level" (all handlers given in a single call to push_handlers()) gets popped.
You can also try this code with Online Python Compiler
Run Code

 

By collecting related event handlers in a single class, you may apply the same pattern in an object-oriented way. A GameEventHandler class is defined in the example below. A window can be pushed on and popped off with an instance of that class: 

 

class GameEventHandler:
    def when_key_pressed(self, symbol, modifiers):
        print(‘The key pressed in game')
        return True
 def when_mouse_pressed(self, x, y, button, modifiers):
        print('The mouse button pressed in-game’')
        return True

game_handlers = GameEventHandler()
def initilize_game()
    window.push_handlers(game_handlers)

def break_game()
    window.pop_handlers()
You can also try this code with Online Python Compiler
Run Code

Creating your own event dispatcher

The windowplayer, and other event dispatchers are provided by pyglet, but it also provides a public interface for creating and dispatching your own events.

The following are the steps of creating an event dispatcher:

1. EventDispatcher subclass

2. For each event that your subclass will recognize, use the register_event_type() class method.

3. To generate and dispatch an event, call dispatch_event().

A hypothetical GUI widget in the following example offers multiple events:

 

class ClankingWidget(pyglet.event.EventDispatcher):
    def clank(self):
        self.dispatch_event('on_clank')
  def click(self, clicks):
        self.dispatch_event('on_clicked', clicks)
 def when_clanked(self):
        print('Default clank handler invoked .')

ClankingWidget.register_event_type('when_clanked')
ClankingWidget.register_event_type('on_clicked')
You can also try this code with Online Python Compiler
Run Code


Following that, event handlers can be attached as specified earlier:

widget = ClankingWidget()

@widget.event
def when_clanked():
    pass

@widget.event
def when_clicked(clicks):
    pass

def override_when_click(clicks):
    pass
widget.push_handlers(on_clicked=override_on_clicked)
You can also try this code with Online Python Compiler
Run Code


The EventDispatcher provided by the pyglet event framework is responsible for disseminating the event to all attached handlers or ignoring it if no handlers exist.

There is no instance overhead on objects with no event handlers attached (the event stack is created only when required). Because of this, EventDispatcher can be used on lightweight objects that don't always contain handlers. Even though hundreds of these objects may be produced and destroyed every second, and most may not require an event handler, a player is an EventDispatcher.

Implementing the Observer pattern

The Publisher/Subscriber design pattern, commonly known as the Observer design pattern, is a straightforward technique to decouple program components. It is essential to any Model-View-Controller architecture and is used extensively in many large software projects, such as Java's AWT and Swing GUI toolkits and the Python logging module.

You can use EventDispatcher to quickly add observable components to your application.

 

#  Defining the subject
class ClockTimer(pyglet.event.EventDispatcher):
    def tick(self):
        self.dispatch_event('on_update')
ClockTimer.register_event_type('on_update')

# Making the Abstract  class named Observer
class Observer:
    def __initialize__(self, subject):
        subject.push_handlers(self)

# Moving on with Concrete observer
class DigitalClock(Observer):
    def on_update(self):
        pass

# Concrete observer
class AnalogClock(Observer):
    def on_update(self):
        pass

timer = ClockTimer()
clock_digital = DigitalClock(timer)
clock_analog = AnalogClock(timer)
You can also try this code with Online Python Compiler
Run Code

 

When the timer is "ticked," the two clock objects will be notified, despite neither the timer nor the clocks requiring prior knowledge of the other. Any relationship between subjects and observers can be created during object formation.

Frequently Asked Questions 

What is pyglet?

Pyglet is a Python library that provides an object-oriented application programming interface for developing games and other multimedia applications. Pyglet is a BSD-licensed program that runs on Microsoft Windows, macOS, and Linux.

How to stack event handlers in pyglet?

EventDispatcher lets you stack event handlers on top of one another. It's common to attach multiple event handlers to a single event instead of replacing event handlers. push_handlers() method adds an event handler to the stack.

How to Implement the Observer pattern?

The Publisher/Subscriber design pattern, commonly known as the Observer design pattern, is a straightforward technique to decouple program components. It is essential to any Model-View-Controller architecture and is used extensively in many large software projects, such as Java's AWT and Swing GUI toolkits and the Python logging module. You can use EventDispatcher to quickly add observable components to your application.

Conclusion 

In this article, we have extensively discussed the pyglet event framework; further, we have discussed its functions and addressed the observer pattern with coded examples.

After reading about the pyglet event framework, are you not feeling excited to read/explore more articles on the topic pyglet framework? Don't worry; Coding Ninjas has you covered. To learn, see Operating SystemUnix File SystemFile System Routing, and File Input/Output.

Refer to our Guided Path on Coding Ninjas Studio to upskill yourself in Data Structures and AlgorithmsCompetitive ProgrammingJavaScriptSystem Design, and many more! If you want to test your competency in coding, you may check out the mock test series and participate in the contests hosted on Coding Ninjas Studio! But if you have just started your learning process and are looking for questions asked by tech giants like Amazon, Microsoft, Uber, etc., you must look at the problemsinterview experiences, and interview bundle for placement preparations.

Nevertheless, you may consider our paid courses to give your career an edge over others!

Do upvote our blogs if you find them helpful and engaging!

Happy Learning!

Live masterclass