16. Event-Driven Programming

Most programs and devices like a cellphone respond to events — things that happen. For example, you might move your mouse, and the computer responds. Or you click a button, and the program does something interesting. In this chapter we’ll touch very briefly on how event-driven programming works.

Events don’t play nice with our ebook

In most other chapters of our ebook, you can run Python code directly in the book. However, in this chapter, you can’t, because event-driven programs don’t really work all that well in the ebook. So you’ll need to cut-and-paste the code samples over to IDLE in order to run the examples in this chapter.

16.1. Keypress events

Here’s a program with some new features. Copy it into your workspace, run it. When the turtle window opens, press the arrow keys and make tess move about!

Here are some points to note:

  • We need the call to the window’s listen method at line 31, otherwise it won’t notice our keypresses.
  • We named our handler functions h1, h2 and so on, but we can choose better names. The handlers can be arbitrarily complex functions that call other functions, etc.
  • Pressing the q key on the keyboard calls function h4 (because we bound the q key to h4 on line 26). While executing h4, the window’s bye method (line 24) closes the turtle window, which causes the window’s mainloop call (line 31) to end its execution. Since we did not write any more statements after line 32, this means that our program has completed everything, so it too will terminate.
  • We can refer to keys on the keyboard by their character code (as we did in line 26), or by their symbolic names. Some of the symbolic names to try are Cancel (the Break key), BackSpace, Tab, Return(the Enter key), Shift_L (any Shift key), Control_L (any Control key), Alt_L (any Alt key), Pause, Caps_Lock, Escape, Prior (Page Up), Next (Page Down), End, Home, Left, Up, Right, Down, Print, Insert, Delete, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, Num_Lock, and Scroll_Lock.

16.2. Mouse events

A mouse event is a bit different from a keypress event because its handler needs two parameters to receive x,y coordinate information telling us where the mouse was when the event occurred.

There is a new turtle method used at line 14 — this allows us to move the turtle to an absolute coordinate position. (Most of the examples that we’ve seen so far move the turtle relative to where it currently is). So what this program does is move the turtle (and draw a line) to wherever the mouse is clicked. Try it out!

If we add this line before line 14, we’ll learn a useful debugging trick too:

Because we can easily change the text in the window’s title bar, it is a useful place to display occasional debugging or status information. (Of course, this is not the real purpose of the window title!)

But there is more!

Not only can the window receive mouse events: individual turtles can also have their own handlers for mouse clicks. The turtle that “receives” the click event will be the one under the mouse. So we’ll create two turtles. Each will bind a handler to its own onclick event. And the two handlers can do different things for their turtles.

Run this, click on the turtles, see what happens!

16.3. Automatic events from a timer

Alarm clocks, kitchen timers, and thermonuclear bombs in James Bond movies are set to create an “automatic” event after a certain interval. The turtle module in Python has a timer that can cause an event when its time is up.

On line 16 the timer is started and set to explode in 2000 milliseconds (2 seconds). When the event does occur, the handler is called, and tess springs into action.

Unfortunately, when one sets a timer, it only goes off once. So a common idiom, or style, is to restart the timer inside the handler. In this way the timer will keep on giving new events. Try this program:

16.4. An example: state machines

A state machine is a system that can be in one of a few different states. We draw a state diagram to represent the machine, where each state is drawn as a circle or an ellipse. Certain events occur which cause the system to leave one state and transition into a different state. These state transitions are usually drawn as an arrow on the diagram.

This idea is not new: when first turning on a cellphone, it goes into a state which we could call “Awaiting PIN”. When the correct PIN is entered, it transitions into a different state — say “Ready”. Then we could lock the phone, and it would enter a “Locked” state, and so on.

A simple state machine that we encounter often is a traffic light. Here is a state diagram which shows that the machine continually cycles through three different states, which we’ve numbered 0, 1 and 2.

_images/fsm_traffic_lights.png

We’re going to build a program that uses a turtle to simulate the traffic lights. There are three lessons here. The first shows off some different ways to use our turtles. The second demonstrates how we would program a state machine in Python, by using a variable to keep track of the current state, and a number of different if statements to inspect the current state, and take the actions as we change to a different state. The third lesson is to use events from the keyboard to trigger the state changes.

Copy and run this program. Make sure you understand what each line does, consulting the documentation as you need to.

The new Python statement is at line 43. The global keyword tells Python not to create a new local variable for stateNum (in spite of the fact that the function assigns to this variable at lines 47, 51, and 55). Instead, in this function, stateNum always refers to the variable that was created at line 40.

What the code in advance_state_machine does is advance from whatever the current state is, to the next state. On the state change we move tess to her new position, change her color, and, of course, we assign to stateNum the number of the new state we’ve just entered.

Each time the space bar is pressed, the event handler causes the traffic light machine to move to its new state.

16.5. Glossary

bind
We bind a function (or associate it) with an event, meaning that when the event occurs, the function is called to handle it.
event
Something that happens “outside” the normal control flow of our program, usually from some user action. Typical events are mouse operations and keypresses. We’ve also seen that a timer can be primed to create an event.
handler
A function that is called in response to an event.