Vizard 7 » Reference » Events » Event basics
7.6

Event Basics

Most user interaction involves handling events (keyboard interaction, the clicking of mouse buttons, timer expiration, etc.). Vizard creates events for many standard purposes. You can even create your own events. This section describes the basics in handling events.

Registering callbacks

To be notified of an event, we need to create a callback function and register it with Vizard. The callback function will be called when the event occurs. The callback function we create will depend on the type of event being registered. For example, a key down event passes the callback function a single value. So our function would look something like this:

def onKeyDown(key):
    #Do something with 'key' variable
    pass

The name of our function and the name of the argument does not matter. The important thing is that our function accepts the correct number of arguments. Now we need to tell Vizard to call this function when a key is pressed. To do this we will use the viz.callback() command. This command requires two arguments, 1) the event ID and 2) the name of the callback function. So the code for registering our callback will look like this:

viz.callback(viz.KEYDOWN_EVENT,onKeyDown)

The onKeyDown function will now be called every time a viz.KEYDOWN_EVENT occurs. This is fine and dandy, but what if we decide that we don't want key press events anymore. We can tell Vizard to unregister a callback associated with an event. To do this we just need to pass the value None in place of the callback function. The code will look like this:

viz.callback(viz.KEYDOWN_EVENT,None)

Vizard only allows one global callback function to be registered per event. However, there might be cases where we need multiple callback functions per event. Drat! Looks like we're out of luck. But wait, here come event classes to the rescue!

Event classes

Event classes are objects that can register their own callbacks. Think of the viz.callback() command as using a global instance of an event class. Here is quick example of using an event class to register a callback for a key down event:

class MyEventClass(viz.EventClass):
    def __init__(self):
        #IMPORTANT: We need to initialize base class
        viz.EventClass.__init__(self)
       
        #Register callback with our event class
        self.callback(viz.KEYDOWN_EVENT,self.onKeyDown)
       
    def onKeyDown(self,key):
        #Do something with 'key' variable
        pass
       
MyEventClass()

To use event classes we need to define our own class that inherits from viz.EventClass. It is important that we initialize the base class in our __init__ method. If we don't do this the event class will not function properly. Registering callbacks is similar to registering global callbacks, except that we use the inherited self.callback() method of the event class. The function we pass to the callback method can be any callable python object, however it is common to pass a method of the event class.

Note: A common mistake is for people to leave out the self parameter of the callback function in their event class. Remember that python methods must explicitly declare the instance of the class as the first argument.

When multiple callbacks are registered for an event, Vizard will call them in the order they were registered in. There are times where we will need to explicitly control the order in which a callback will be called. Vizard provides this functionality through event priorities.

Event priority

Each callback has an associated priority number. When an event occurs, Vizard will execute each callback registered for the event in order of lowest to highest priority. When you register a callback without specifying a priority, Vizard will assign the callback a priority of 0. The priority can be any positive or negative integer value. For example, let's modify our global key down callback to use a priority of -10:

viz.callback(viz.KEYDOWN_EVENT,onKeyDown,priority=-10)

If we were to create an event class that also handles a key down event, but at the default priority, our global function would be called first since it has a lower priority value.

 

So you might ask, what's the point of having a callback execute earlier than other callbacks? This feature is handy when you want to stop an event from being passed on to other callbacks.

Stopping other callbacks for the same event

When a callback is executed, it can notify Vizard that it doesn't want the event to be passed on to any remaining callbacks. To do this, use the viz.setEventAction command in your callback function. Here is our key down callback modified to stop the event from being passed on:

def onKeyDown(key):
    #Do something with 'key' variable
    viz.setEventAction(viz.EVENT_STOP)
viz.callback(viz.KEYDOWN_EVENT, onKeyDown, priority=-10)

There are many internal Vizard tasks that handle events at different priorities and stop the events in certain cases. Here is list of internal tasks that handle input events (i.e. mouse and keyboard):

Priority name

Value

Description

viz.PRIORITY_GUI_HANDLER

-20

Handles user interaction with GUI items (button, checkbox, slider, etc..). It will stop mouse button events from being passed on. Textbox objects will also stop keyboard events from being passed.

viz.PRIORITY_CAMERA_HANDLER

-10

Processes input events for camera navigation handlers. It does not stop events from being passed.

viz.PRIORITY_DEFAULT_KEY

-5

Implements the default key functionality which includes the following:

  • Escape - Quit Vizard
  • F1 - Toggle HTML display
  • F2 - Toggle fullscreen mode
  • F3 - Toggle polygon, wire, and point rendering mode
  • F4 - Toggle framerate display
  • F8 - Reset active camera handler
  • Ctrl+F9 - Capture screenshot
  • Ctrl+F12 - Toggle AVI recording
  • Ctrl+F6 - Toggle docking of window within Vizard IDE
  • Alt+I - Float window and activate Vizard IDE interactive input

It does not stop events.

Here is a list of internal tasks that handle the update event. None of these tasks will stop the event.

Priority name

Value

Description

viz.PRIORITY_FIRST_UPDATE

-50

Marks the beginning of internal update tasks.

viz.PRIORITY_PLUGINS

-50

Updates sensor, imagegen, and extension plugins.

viz.PRIORITY_INPUT

-40

Checks for keyboard/mouse input. This is when keyboard/mouse events are triggered.

viz.PRIORITY_NETWORK

-30

Checks for network messages. This is when network events are triggered.

viz.PRIORITY_SCENEGRAPH

-20

Updates internal scenegraph. This is when avatars, animation paths, and viewpoints are updated.

viz.PRIORITY_TIMERS

-10

Check for expired timers. This is when timer events are triggered.

viz.PRIORITY_DEFAULT

0

Updates events using default priority.

viz.PRIORITY_PHYSICS

20

Update physics engine. This is when physics collision events are triggered.

viz.PRIORITY_LINKS

40

Update links.

viz.PRIORITY_MEDIA

50

Updates audio, video, and 3D sounds.

viz.PRIORITY_LAST_UPDATE

50

Marks the end of internal update tasks.

Event callbacks in the action library

The action library has some methods of registering callback functions ( <vizact>.onmousedown , <vizact>.onkeydown, <vizact>.ontimer, etc. ). To disable these callbacks, use <EventFunction>.setEnabled( viz.OFF ).

#The callback function.
def myCallback(word):
    print( word)
#Register a keydown event. 
event_handle = vizact.onkeydown( ' ', myCallback, 'key event')
#Disable the event with another key down event.
vizact.onkeydown(viz.KEY_END, event_handle.setEnabled, viz.OFF )

See also

In this section:

Custom Events

Event Reference

Other sections:

Action basics

Task basics

Director basics

Timer basics

Example scripts:

Event callbacks

Event handling

Event class timer