Responding to Mouse Clicks¶
By the end of this lesson you'll be able to:
- Register a function as a click handler using
screen.onscreenclick() - Use the
xandyarguments your handler receives to draw at the click location - Build a program that responds to the user in real time
Every program so far runs from top to bottom and then stops. Event-driven programs are different — they set up a handler function and then wait. When the user clicks the canvas, the handler is called with the exact coordinates of the click. Your code then decides what to draw there.
Welcome to This Lesson!
Click anywhere on the canvas and a shape appears — that's an event-driven program!
Today you'll make Monty respond to wherever you click. Let's code it together!
Event Handlers¶
An event handler is a function you write and then register with the screen. Python calls it automatically whenever the event occurs — you don't call it yourself:
1 2 3 4 5 6 7 | |
screen.onscreenclick(on_click) tells Python: "when someone clicks the canvas, call on_click with the click coordinates." Your function receives x and y automatically.
Sample Code¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | |
What Do You Think Will Happen?
After you click Run, the canvas waits for your clicks.
Each click draws a circle at that position. What do you think happens to the color each time you click?
Make your guess — then click Run and try clicking the canvas!
Try It Now¶
Click Run, then click anywhere on the drawing canvas to place a circle there. No account needed — everything runs in your browser.
Were you right? Each click draws a filled circle at exactly that spot, cycling through red, orange, green, blue, purple, and pink — the color advances with every click.
How It Works¶
screen.onscreenclick(on_click) registers your function. Each time the canvas is clicked, Python calls on_click(x, y) with the pixel coordinates of the click. Your function then goes to that location and draws.
click_count is stored as a list with one item ([0]) rather than a plain variable. This is a Python scoping trick: plain variables inside a nested function can't be updated directly — but list items can. click_count[0] += 1 increments the counter safely.
Explanation Table¶
| Line | What it does |
|---|---|
screen = turtle.Screen() |
Gets a handle to the drawing window |
screen.onscreenclick(on_click) |
Registers on_click as the function to call on each canvas click |
def on_click(x, y): |
The handler — x and y are provided automatically by the screen |
click_count = [0] |
A counter stored in a list so it can be updated inside the handler |
click_count[0] % len(colors) |
Cycles through the color list with each click |
The x, y Come Free
You never call on_click() yourself — the screen calls it for you and fills in x and y
automatically. Your job is just to decide what to draw at those coordinates!
Learning Check¶
Your Turn — Draw Stars Instead of Circles
The program below draws a circle on every click. Change the drawing code inside on_click
so it draws a five-pointed star at the click position instead.
Hint: a star uses for i in range(5): forward(30); right(144).
Experiments¶
Try these changes to the click-to-draw code. Predict first, then test!
-
Change
monty.circle(20)tomonty.circle(random.randint(10, 40))(addimport randomat the top). You'll know it worked when each click produces a circle of a random size. -
Change
screen.bgcolor('lightyellow')toscreen.bgcolor('black')and add bright colors to the list. You'll know it worked when the circles look like colorful bubbles on a dark background. -
After
on_clickruns, addmonty.write(str(click_count[0]), font=("Arial", 12, "normal"))to number each circle. You'll know it worked when a number appears next to each circle showing the order it was clicked. -
Change
monty.circle(20)to a small polygon:for i in range(6): monty.forward(20); monty.right(60). You'll know it worked when clicking places hexagons instead of circles. -
Add
if click_count[0] >= 5: returnat the very start ofon_clickto limit clicks to 5. You'll know it worked when clicks after the fifth one have no effect.
Great Work!
You've written an event-driven program — the same pattern used in every button, menu, and
game in the world. Every click, tap, and keypress works exactly like this under the hood!
Let's code it together!