IntroductionIntroduction. Lesson 1 A guide around the Glowscript VPython interface, and introduction to some basic programming concepts. Lesson 2 Create code to produce simple 3-D objects. Lesson 3 Make an object move in a linear fashion. Lesson 4 Make an object rotate around a point. Lesson 5 Connect objects together using common attributes. Lesson 6 Create a new object by amalgamating other objects. Lesson 7 Apply textures and images to the surface of shapes. Lesson 8 Demonstration of how keyboard and mouse events are handled by VPython Lesson 9 Allow the user to interact with the scene and objects within. Lesson 10 Take a shape and extrude it along a path to create novel objects. Lesson 11 The scene window and its properties Lesson 12 A task to use all the lesson skills to create some digital art! Glossary Terms and language used in programming for VPython

Lesson 8 - Events

In this lesson we look at mouse and keyboard events and how VPython reports them.

Objectives

By the end of the lesson the student should be able to:

Timings
Teaching: 40 min
Exercises: 20 min

Description

Glowscript VPython can detect many mouse and keyboard events:
mousedown
mouseup
mouseclick
mouseleave
mouseenter
mousemove

keydown
keyup
keypress

Note: There is currently no way in GlowScript to handle right button or middle button events.

Events in VPython are controlled by scene.
The scene is everything within the graphics window which is not a shape, such as the width and height of the graphics window,
the background colour and lighting, the camera position and the degree of zoom.
Lesson 11 will look at the scene in more detail.

The program

The code below displays two labels which are updated through keyboard and mouse events.

# Define two labels with default texts
txt = label(pos=vector(0,6,0), text='No keys pressed', align='center',height=36, color=color.green)
txt2 = label(pos=vector(0,-3,0), text='Nothing pressed', align='center',height=36, color=color.green)

# Define a function that is called when a key or mouse is pressed
def getevent(ev):
 k = keysdown() # a list of keys that are down

#Define an "if" statement to 'look for' mouse events
 if ev.event == 'mousedown':
  txt.text='You mousedowned at\n' + ev.pos
  txt.color=color.yellow
 else if ev.event == 'mouseup':
  txt.text='Nothing clicked'
  txt.color=color.red

#Define an "if" statement to 'look for' keyboard events   txt2.text='You are holding down\n' + k
 else if ev.event == 'keydown':
  txt.text='You pressed\n' + ev.key
  txt.color=color.red
  txt2.text='You are holding down\n' + k

#Define an "if" statement to 'look for' key events and reset text label back to default
 if ev.event == 'keyup':
  txt.text='No keys pressed'
  txt2.text='Nothing pressed'
  txt2.color=color.green

#Tell the "scene" to use the getevent function whenever a key or mouse is pressed
scene.bind("mousedown", getevent)
scene.bind("mouseup", getevent)
scene.bind("keydown", getevent)
scene.bind("keyup", getevent)

#Tell the "scene" which events to respond to
scene.waitfor('mousedown mouseup keydown keyup ')

Things to note

The last line of the program asks the scene to wait for the specified events.
A function getevent(ev) is defined and it is bound to the event by the scene.bind() method.
Now when the scene is clicked or a key is pressed, the getevent function is fired. When it is fired it passes the event data to the function via the ev variable.
VPython keeps track of which keys are down using the keysdown() function, which returns a list of all the keys which are pressed.
The getevent function then filters the event recieved and alters the text in the label accordingly.
The ev variable in getevent is user defined. For example it could be 'e' or 'evt' or 'zxpw', but will contain the event data.
Essentially think of the ev variable as a place where VPython 'puts' the details of the event.
Here we use ev.event and ev.key, but there are more, such as ev.type, ev.ctrl, ev.shift, ev.alt and ev.which.

Note: Keys with multiletter names are 'backspace', 'caps lock', 'tab', 'shift', 'ctrl', 'alt', 'pageup', 'pagedown', 'end', 'home', 'left', 'up', 'right', 'down', 'insert', 'delete', 'break', and the function keys 'f1' through 'f10'.

 

 

Exercise 1

Copy the program above and do the following:
Modify the program to make the word 'HELLO!' appear in the bottom label in magenta, when the user presses 'ctrl'+ 'alt' + shift.

Solution to Exercise 1

# Define two labels with default texts
txt = label(pos=vector(0,6,0), text='No keys pressed', align='center',height=36, color=color.green)
txt2 = label(pos=vector(0,-3,0), text='Nothing pressed', align='center',height=36, color=color.green)

# Define a function that is called when a key or mouse is pressed
def getevent(ev):
 k = keysdown() # a list of keys that are down

#Define an "if" statement to 'look for' mouse events
 if ev.event == 'mousedown':
  txt.text='You mousedowned at\n' + ev.pos
  txt.color=color.yellow
 else if ev.event == 'mouseup':
  txt.text='Nothing clicked'
  txt.color=color.red
  txt2.text='You are holding down\n' + k

#Define an "if" statement to 'look for' keyboard events
 else if ev.event == 'keydown':
  txt.text='You pressed\n' + ev.key
  txt.color=color.red
  txt2.text='You are holding down\n' + k

#Define an "if" statement to 'look for' ctrl, alt and shift keys
 if'ctrl' in k and 'alt' in k and 'shift' in k: # solution
  txt2.text='HELLO!'
  txt2.color=color.magenta
 else:
  txt2.text='You are holding down\n' + k

#Define an "if" statement to 'look for' key events and reset text label back to default
 if ev.event == 'keyup':
  txt.text='No keys pressed'
  txt2.text='Nothing pressed'
  txt2.color=color.green

#Tell the "scene" to use the getevent function whenever a key or mouse is pressed
scene.bind("mousedown", getevent)
scene.bind("mouseup", getevent)
scene.bind("keydown", getevent)
scene.bind("keyup", getevent)

#Tell the "scene" which events to respond to
scene.waitfor('mousedown mouseup keydown keyup ')

-

Conclusion

You should now be able to:
 Create a label containing text.
 Detect keyboard and mouse events.
 Define a function.
 Bind a function to an event.
 Bind an event to an object through a function.
 Look for multiple keys being down.