Freehand Drawing!
Drawing freehand is like drawing with a pencil on paper. You can write code so you can drag the turtle around on the screen to draw.
To do this, you need to listen for the drag event. Dragging occurs when you drag the turtle (the pencil) around the screen. The drag event can be listened for by sending the ondrag message to the turtle as follows.
pointsToDraw = [] def dragHandler(x,y): pointsToDraw.append((x,y)) t.ondrag(dragHandler)
To get freehand drawing to work, the dragHandler event handler can't do very much (or the program will eventually get an error). The first line of code above creates an empty list (represented by [ ]). The dragHandler event handler is called with the x,y coordinate of the turtle location as it is being dragged. Each (x,y) tuple is appended to the list called pointsToDraw.
As the turtle (the pencil) is dragged around the screen, the turtle can draw a line to its next coordinate. To get this to work we'll create another event handler to run every few milliseconds. This event handler is triggered by a timer event.
def timerHandler(): if len(pointsToDraw) > 0: x,y = pointsToDraw.pop(0) w = int(pointSize.get()) t.width(w) c = colorVar.get() t.color(c) t.goto(x,y) screen.ontimer(timerHandler,5) screen.ontimer(timerHandler,5)
Try this out! What you are going to notice is that the turtle does not keep up with the mouse very well. This is because the turtle is set to draw slowly by default so you can watch it. We can speed that up by sending a speed message to the turtle and a tracer message to the screen. You put this code in your main function outside any of your event handling code.
t.speed(100) screen.tracer(10000)
When we add this code, the turtle graphics program will no longer update the screen each time the turtle draws something. This allow the turtle to speed up, but at the expense of us having to tell the screen to update. The following line of code updates the screen.
screen.update()
This needs to be done after the program draws something on the screen. So for instance, in the timer handler above after you have sent the goto message to the turtle, you should tell the screen to update.
Don't forget to tell the screen to update in the click handler code as well.
Now You Try It
A turtle can pick up and put down its tail and so we could add to our program to allow the user to pick up and put down the pen as they are drawing. Add a button to the program that allows the user to keep track of whether they are drawing or not. To do this, you need a Boolean variable. A Boolean variable is either True or False. You can set data["penup"] to True in your program. Then your button can toggle the penup value either on or off. Here is the handler for the Pen Up/Down button.
data = {} data["penup"] = False
def penHandler(): data["penup"] = not data["penup"] if data["penup"]: penButton.config(text="Pen Up") else: penButton.config(text="Pen Down") penButton = tkinter.Button(frame, \ text="Pen Down",command=penHandler) penButton.pack()
The first line of code above creates a dictionary called data. This is necessary in this program for a very subtle reason. The penHandler code needs to be able to set the value of the penup to True or False. However, that penup variable needs to remember its state and be available in other event handlers. To make the penup value available in other event handlers and to be able to set it in the penHandler event handler you could either make a global variable or you could use a dictionary like I did here. To completely understand why, take Computer Science when you get to Luther College! It is an exciting and interesting field to study!
With this code added to your program, you can add code to your clickHandler and your dragHandler to check the value of the penup Boolean value and either pick up the pen with the line of code
t.penup()
or put it back down with the line of code
t.pendown()
to either draw or stop drawing as you move the turtle on the screen.
If you get stuck, ask for help!