Python
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax and Data Types
-
Section 3: Collections
-
39: Set Operations: Union, Intersection, Difference
-
Section 4: Control Flow
-
Section 5: Functions
-
Section 6: Turtle Graphics and Early Practice Projects
-
Section 7: Working with Files and I/O
-
Section 8: Regular Expressions
-
Section 9: Object-Oriented Python
-
Section 10: Error Handling
-
Section 11: Modules and Packages
-
Section 12: Iterators, Generators, and Functional Tools
-
Section 13: Decorators and Metaprogramming
-
Section 14: Concurrency and Parallelism
-
Section 15: Working with Dates, Times, and Numbers
-
Section 16: Standard Library Deep Dive I: Data Structures
-
Section 17: Standard Library Deep Dive II: System and Introspection
-
Section 18: Standard Library Deep Dive III: Security and Encoding
-
Section 19: Standard Library Deep Dive IV: Text and Data Utilities
-
Section 20: Networking and Web Basics
-
Section 21: Working with Databases
-
Section 22: Testing and Quality
-
Section 23: Advanced Typing
-
Section 24: Context Managers and Resource Handling
-
Section 25: Text, Unicode, and Binary Data
-
Section 26: More Functional and Iteration Tools
-
Section 27: Data Validation and Configuration
-
Section 28: Working with Images and Media
-
Section 29: Property-Based and Documentation Testing
-
Section 30: Packaging and Deployment
-
Section 31: Performance and Internals
-
Section 32: Design Patterns in Python
-
Section 33: GUI Programming
-
Section 34: Security Basics
-
Section 35: Data Structures and Algorithms
-
Section 36: Practical Projects
-
Section 37: Capstone Projects
-
Section 38: Interview and Algorithm Practice
-
Section 39: Writing Idiomatic Python
88: Building a Simple Drawing App with Turtle
We've spent a lot of time in the console, but today I want to get something visual on the screen. The turtle module is an old-school favorite, and while it's often used for teaching kids, it's actually a fantastic way to understand how coordinate systems and event-driven programming work in Python. We're going to build a simple "Sketchpad" app where you can click anywhere on the screen to draw lines.
Setting up our canvas and the artist
First, we need a window and a turtle object. I usually like to name my turtle something specific rather than just using the default, as it makes the code feel more like I'm controlling an object. I'll call mine artist. We also need to set up the Screen object to handle the window properties.
import turtle
screen = turtle.Screen()
screen.title("My Python Sketchpad")
screen.setup(width=600, height=600)
artist = turtle.Turtle()
artist.speed(0) # Let's make it move instantly
artist.shape("circle")
Making the turtle follow our mouse
The core of a drawing app is interactivity. We don't want to write a script that just draws a square and stops; we want the program to wait for us. I'm going to define a function that takes the x and y coordinates of a mouse click and tells the turtle to go there. Then, I'll bind that function to the screen's click event.
def draw_to_click(x, y):
artist.goto(x, y)
screen.onclick(draw_to_click)
screen.listen()
If you run this now, it almost works. You click, and the turtle zips over to that spot, leaving a line behind it. But there's a problem.
Fixing that annoying starting line
I just noticed that every time I start the app and make my first click, there's a big, ugly line stretching from the center of the screen (0,0) to wherever I clicked. It ruins the "blank canvas" feel. This happened because the turtle starts with its pen down by default.
The fix is simple: I need to lift the pen up before the turtle moves to the first point, and then put it back down once it arrives. I'll modify the draw_to_click function, but wait—if I put penup() at the start of the function, I'll never draw any lines at all! I only want the pen up for the very first move.
Instead of a complex boolean flag, I'll just lift the pen once at the very beginning of the script and put it down the moment the first click happens. Let's adjust the logic:
# Add this right after creating the artist
artist.penup()
def draw_to_click(x, y):
artist.pendown() # Put pen down on the first click, and keep it down
artist.goto(x, y)
Now, the first click "lands" the turtle on the canvas without dragging a line from the center. Much cleaner.
Adding a way to start over
Finally, no drawing app is complete without a "Clear" button. Since we don't have a full GUI toolkit like Tkinter linked up with buttons yet, I'll use a keyboard event. I'll map the 'c' key to clear the screen and reset the turtle's position.
def clear_canvas():
artist.clear()
artist.penup()
artist.home()
screen.onkey(clear_canvas, "c")
# Remember to call mainloop so the window doesn't close immediately
screen.mainloop()
I've found that artist.clear() is better than screen.clear() because screen.clear() wipes out all the event listeners we just set up. Always be careful about what level of "reset" you're calling in Turtle.
📋 Practical Task
Adding a Color-Switcher to your Turtle Sketchpad
Right now, our sketchpad only draws in black. Your task is to enhance the app so that the user can change the pen color using the keyboard.
- Modify the code so that pressing the 'r' key changes the pen color to red.
- Modify the code so that pressing the 'b' key changes the pen color to blue.
- Modify the code so that pressing the 'g' key changes the pen color to green.
Make sure your new functions are properly bound using screen.onkey() and that they don't interfere with the existing clear_canvas functionality.
There are no comments for now.