The ocempgui.events
module provides a small
and fast event management system. It is currently separated into
three different classes, of which the most important is the
EventManager
class. Besides the
EventManager
, an
Event
class for sending event data and an
EventCallback
class for connecting
functions or methods to signals are available.
To create an own event driven application system or to enhance an existing application, only a few guidelines have to be respected and only a minimal set of changes be made on existing code. You will need to
enable objects to receive events,
set up the event management system.
To understand, what you are doing and to know the pitfalls of the event management system, you first have to know, how it works. The next subsection will give you a short explanation of it.
The event management system of OcempGUI uses a simple approach using signal slots. This means, that objects will register themselves only for specific event types, of which they want to be notified. Any other event will not be sent to them.This reduces the overhead of events the objects have to deal with (either by dropping or processing them) and improves the performance and scalability of the event management system (especially with many objects).
An object, which shall be event aware, should inherit from the
INotifyable
class and implement its
notify()
method, which will receive
events distributed by the EventManager
.
The signature of the method looks like the following:
class OwnObject (INotifyable): ... def notify (self, event): ...
Your classes do not need to explicitly inherit from
INotifyable
, but have to implement the
notify()
method with its correct
signature.
The event
argument of the method will be
an Event
object, which can be used to
perform certain actions within the method body then:
class OwnObject (INotifyable): ... def move (self, coords): # Moves the object to the desired coordinates (x, y). self.x = coords[0] self.y = coords[1] print "Moved to %d,%d" % (self.x, self.y) def notify (self, event): # Check the event signal and run a certain action with its data. if event.signal == "clicked": print "Something was clicked!" elif event.signal == "move": # Assuming that the event.data contains a coordinate tuple. self.move (event.data)
Example 12. Enabling an object to receive events
Setting up the main event management is nearly as easy as
enhancing the objects. To add objects to the
EventManager
, the
add_object()
method has to be
invoked. It receives the object to add and a list of signal ids
as arguments. The signal ids will cause the object to be
registered in specific queues, to which events with matching
signal ids then will be sent.
Objects can be removed from the
EventManager
using the
remove_object()
method. The method
allows you to either remove the object from specific
slots or from all
slots, it is registered for, at once.
We use the OwnObject
class of the
previous example and will (un)register it for the signals
"move" and "clicked".
# Create an EventManager and OwnObject instance. manager = EventManager () myobj = OwnObject () # Add the object to the EventManager. manager.add_object (myobj, "move", "clicked") # Remove the object from the 'clicked' slot. manager.remove_object (myobj, "clicked") # Remove the object from _all_ slots it still listens on. manager.remove_object (myobj)
Example 13.
Adding and removing an object to the
EventManager
Now let us proceed to the most important: sending events. To
send events to the objects of the
EventManager
, you can use the
emit()
method. It receives two
arguments, which will become the signal and data of a
Event
object. The
Event
will be created by the
EventManager
and then sent to the
matching objects. So all you have to do is to pass the
emit()
method the correct information
for the event.
Both arguments the emit()
receives,
have no limitations of type, length or whatsoever. It is up to
you to to send correct information through the event management
system and to check for correct information on the object side.
# Send events to the registered objects via the emit() method. manager.emit ("clicked", None) manager.emit ("move", (10, 10))
Example 14.
Sending events through the EventManager
The following example is a complete example based on the
excerpts from above. You can find it as python script under
examples/eventmanager.py
# EventManager usage example. from ocempgui.events import EventManager, INotifyable # Create a new event capable object. This can be acquired by adding a # 'notify ()' method to the object, which receives a single argument. class OwnObject (INotifyable): def __init__ (self): self.x = 0 self.y = 0 def move (self, coords): # Moves the object to the desired coordinates (x, y). self.x = coords[0] self.y = coords[1] print "Moved to %d,%d" % (self.x, self.y) def notify (self, event): # Check the event signal and run a certain action with its data. if event.signal == "clicked": print "Something was clicked!" elif event.signal == "move": # Assuming that the event.data contains a coordinate tuple. self.move (event.data) # Create an EventManager and OwnObject instance. manager = EventManager () myobj = OwnObject () # Add the object to the EventManager. manager.add_object (myobj, "move", "clicked") # Send events to the registered objects via the emit() method. manager.emit ("clicked", None) manager.emit ("move", (10, 10)) # Remove the object from the 'clicked' slot. manager.remove_object (myobj, "clicked") # Send the 'clicked' event once more. manager.emit ("clicked", None) # Remove the object from _all_ slots it still listens on. manager.remove_object (myobj) # Send the 'move' event again. manager.emit ("move", (40, 40))
Example 15. Complete event management example