Section 10.7 Event Handlers
An event handler is a function that you write that will get called automatically by the Python interpreter when the operating system (Windows, MacOS, Android, Linux, iOS, etc.) tells Python that an event happened in the window of a running Python program. If the end user clicks in the window where your Python program is running, that window gets the operating system focus. If the user then clicks on a user interface widget in that window, the operating system tells Python where the click happened and Python figures out if the click happened on a widget. If you have registered an event handler for mouse clicks on that widget, then that function is called.
We can generally think about two types of handlers. First there are widget handlers. These are functions you write that run code in response to the user interacting with the graphical user interface widgets you have put on screen. This may be clicking on a button, selecting an item from a drop-down menu, moving a slider, checking or unchecking a checkbox, entering text into an input field, or moving a scrollbar. The second type of handler is a more general mouse or keyboard handler. These handlers get called when the user performs actions with an input device, while your program is the program in focus. So, if the user has opened your Python program, but then switched over to type up a letter in MS Word, your Python program will not get the user’s mouse input or keyboard input while they are working in MS Word. But, when the user switches back to your Python program, then your handlers will get their input actions and execute.
Subsection 10.7.3 Registering Event Handlers
In addition to writing an event handler function, you also need to register the event handler, so that the Python interpreter knows that you want to receive such events. In some toolkits, you register the event on a separate line of code That is the case in the turtle examples seen in earlier chapters. In the SimpleGUI module, you register handlers in the same line of code that you use to create the user interface widget (for buttons and textboxes), but you have separate instructions to register the more general event handlers that respond to key presses and mouse clicks.
In all cases, once you have added GUI elements to the window, written the event handlers, and registered the event handlers, you need something to tell the Python interpreter to start listening for events (in the Turtle module it’s wn.listen()
; in the SimpleGUI module it’s frame.start()
).
Check your understanding
Checkpoint 10.7.1.
import simplegui
CANVAS_WIDTH = 400
CANVAS_HEIGHT = 400
circle_list = []
canvas_col = "White"
# GUI Control Handlers
def draw(canvas):
for index in range(len(circle_list)):
canvas.draw_circle(circle_list[index], 10, 3, "Black", "Red")
def clear_handler():
clear_canvas()
def drag(pos):
add_circle(pos)
def add_circle(pos):
circle_list.append(pos)
def clear_canvas():
circle_list.clear()
# Frame
frame = simplegui.create_frame("COMP 1000 Demo", CANVAS_WIDTH, CANVAS_HEIGHT)
frame.set_canvas_background(canvas_col)
# Register Keyboard and Mouse Event Handlers
frame.set_draw_handler(draw)
frame.set_mousedrag_handler(drag)
frame.add_button('Clear', clear_handler)
# Show the frame and start listening
frame.start()
What would happen if a user was running this code in CodeSkulptor3 and clicked on the canvas once?
A circle will be drawn where the user clicked.
It’s reasonable to expect this, but CodeSkulptor3 has unique handlers for both individual mouse clicks and for dragging the mouse click.
A circle is drawn where the user initially clicked, and continues to draw circles on the position of the mouse around the canvas.
Mouse drag handlers only register continuous dragging inputs and not individual clicks. Even if the mouse drag handler recognized the initial click, without dragging the mouse on the canvas there are no more inputs to keep drawing circles.
This code does not run, it contains an error.
Incorrect. Try running this code in CodeSkulptor3 to test what happens yourself.
Nothing happens.
Correct! Mouse drag handlers do not recieve inputs from individual clicks and so nothing is drawn on the canvas.
Checkpoint 10.7.2.
import simplegui
CANVAS_WIDTH = 400
CANVAS_HEIGHT = 400
circle_list = []
canvas_col = "White"
# GUI Control Handlers
def draw(canvas):
for index in range(len(circle_list)):
canvas.draw_circle(circle_list[index], 10, 3, "Black", "Red")
def clear_handler():
clear_canvas()
def drag(pos):
add_circle(pos)
def add_circle(pos):
circle_list.append(pos)
def clear_canvas():
circle_list.clear()
# Frame
frame = simplegui.create_frame("COMP 1000 Demo", CANVAS_WIDTH, CANVAS_HEIGHT)
frame.set_canvas_background(canvas_col)
# Register Keyboard and Mouse Event Handlers
frame.set_draw_handler(draw)
frame.set_mousedrag_handler(drag)
frame.add_button('Clear', clear_handler)
# Show the frame and start listening
frame.start()
What would happen if a user running this code in CodeSkulptor3 held their mouse click and dragged on the canvas?
Circles are drawn continously wherever the user drags their mouse on the canvas.
Correct! The Input Event handler adds the current position of the mouse to ’circle_list’ which is repeatedly drawn on the canvas.
A circle is drawn only where the user initially clicked.
Close! A circle will be drawn there, but not only there! Try running this example in CodeSkulptor3 to test it for yourself.
Nothing happens, this code contains an error.
Incorrect. Try running this example in CodeSkulptor3 to test what happens yourself.
Nothing happens.
Incorrect. Try running this example in CodeSkulptor3 to test what happens yourself.
Checkpoint 10.7.3.
import simplegui
CANVAS_WIDTH = 400
CANVAS_HEIGHT = 400
circle_list = []
canvas_col = "White"
# GUI Control Handlers
def draw(canvas):
for index in range(len(circle_list)):
canvas.draw_circle(circle_list[index], 10, 3, "Black", "Red")
def clear_handler():
clear_canvas()
def drag(pos):
add_circle(pos)
def add_circle(pos):
circle_list.append(pos)
def clear_canvas():
circle_list.clear()
# Frame
frame = simplegui.create_frame("COMP 1000 Demo", CANVAS_WIDTH, CANVAS_HEIGHT)
frame.set_canvas_background(canvas_col)
# Register Keyboard and Mouse Event Handlers
frame.set_draw_handler(draw)
frame.set_mousedrag_handler(drag)
frame.add_button('Clear', clear_handler)
# Show the frame and start listening
frame.start()
Which line of code defines a Widget Event handler function?
add_circle(pos).
This function is called by an Input Event handler.
clear_handler().
This is correct! When a user presses the ’Clear’ button this handler calls on the ’clear_canvas’ function.
drag(pos).
So close! But this line defines an Input Handler function instead of a Widget Handler function.
None of the above.
There is a Widget Event handler defined in the code above. Try running this code in Codeskulptor3 and think about what line of code gets called when a user presses on the button widget.
Checkpoint 10.7.4.
import simplegui
CANVAS_WIDTH = 400
CANVAS_HEIGHT = 400
circle_list = []
canvas_col = "White"
# GUI Control Handlers
def draw(canvas):
for index in range(len(circle_list)):
canvas.draw_circle(circle_list[index], 10, 3, "Black", "Red")
def clear_handler():
clear_canvas()
def drag(pos):
add_circle(pos)
def add_circle(pos):
circle_list.append(pos)
def clear_canvas():
circle_list.clear()
# Frame
frame = simplegui.create_frame("COMP 1000 Demo", CANVAS_WIDTH, CANVAS_HEIGHT)
frame.set_canvas_background(canvas_col)
# Register Keyboard and Mouse Event Handlers
frame.set_draw_handler(draw)
frame.set_mousedrag_handler(drag)
frame.add_button('Clear', clear_handler)
# Show the frame and start listening
frame.start()
Which line of code defines an Input Event handler function?
drag(pos).
Correct! This function is called when the user holds down mouseclick and drags on the canvas.
clear_handler().
Close! This line defines a Widget Event handler.
add_circle(pos).
So close! This function does not define an Input Event handler, but is instead called by one when the user holds mouseclick and drags.
None of the above.
There is an Input Event handler defined in the code above. Try running this code in Codeskulptor3 and think about what line of code gets called when a user holds mouseclick and drags along the canvas.
Checkpoint 10.7.5.
import simplegui
CANVAS_WIDTH = 400
CANVAS_HEIGHT = 400
circle_list = []
canvas_col = "White"
# GUI Control Handlers
def draw(canvas):
for index in range(len(circle_list)):
canvas.draw_circle(circle_list[index], 10, 3, "Black", "Red")
def clear_handler():
clear_canvas()
def drag(pos):
add_circle(pos)
def add_circle(pos):
circle_list.append(pos)
def clear_canvas():
circle_list.clear()
# Frame
frame = simplegui.create_frame("COMP 1000 Demo", CANVAS_WIDTH, CANVAS_HEIGHT)
frame.set_canvas_background(canvas_col)
# Register Keyboard and Mouse Event Handlers
frame.set_draw_handler(draw)
frame.set_mousedrag_handler(drag)
frame.add_button('Clear', clear_handler)
# Show the frame and start listening
frame.start()
Two functions in this example use the same input data from the argument labeled (pos). Which data type does the argument (pos) require?
An X coordinate in the form of an integer.
The ’draw(canvas)’ function cannot draw anything if it only knows where to draw on one axis.
A Y coordinate in the form of an integer.
The ’draw(canvas)’ function cannot draw anything if it only knows where to draw on one axis.
An X coordinate and a Y coordinate in the form of a list.
So close! Because the value is provided by the location of the mouse on the canvas and cannot be altered it is not contained as a list.
An X and a Y coordinate in the form of a tuple.
Correct! Because the input comes from the location of the mouse the data cannot be altered by the code and must be a tuple instead of a list.
You have attempted
of
activities on this page.