Reputation: 19
I'm trying to draw a square using python graphics then erase it after 3 seconds. I have the code below:
import threading as th
import turtle
import random
thread_count = 0
def draw_square():
turtle.goto(random.randint(-200,200), random.randint(-200,200))
for i in range(4):
turtle.forward(100)
turtle.left(90)
def erase_square(x,y):
turtle.pencolor('white')
turtle.fillcolor('white')
turtle.goto(x,y)
turtle.begin_fill()
for i in range(4):
turtle.forward(target_size)
turtle.left(90)
turtle.end_fill()
def square_timer():
global thread_count
if thread_count <= 10:
print("Thread count", thread_count)
draw_square()
T = th.Timer(3, square_timer)
T.start()
The square_update() function will draw 10 squares then stop. I'm trying to make it draw one square then clear it using the erase_square() by painting white over it, then another and repeat the process and stop when it reaches 10. I can't figure how to make the erase function go to the random location of the drawn square and 'erase' it. How can I make it draw and erase the square?
Upvotes: 0
Views: 399
Reputation: 41872
The most straightforward way to clear a drawing is with the clear()
method rather than trying to draw white over the image:
from turtle import Screen, Turtle
from random import randint
def draw_square():
turtle.goto(randint(-200, 200), randint(-200, 200))
turtle.pendown()
for _ in range(4):
turtle.forward(100)
turtle.left(90)
turtle.penup()
def erase_square():
turtle.clear()
screen.ontimer(square_update) # no time, ASAP
def square_update():
draw_square()
screen.ontimer(erase_square, 3000) # 3 seconds in milliseconds
screen = Screen()
turtle = Turtle()
turtle.hideturtle()
turtle.speed('fastest')
turtle.penup()
square_update()
screen.exitonclick()
You can use the undo()
method as @JonathanDrukker suggests, but you have to undo each step. Even for a simple shape like a square, this takes a little thought, but with a complex shape, this is difficult. The number of operations added to the undo buffer don't always match the calls that you make to turtle. But we can get that count from turtle itself, as long as we don't do any other turtle actions between drawing and erasing:
def draw_square():
turtle.goto(randint(-200, 200), randint(-200, 200))
count = turtle.undobufferentries()
turtle.pendown()
for _ in range(4):
turtle.forward(100)
turtle.left(90)
turtle.penup()
return turtle.undobufferentries() - count
def erase_square(undo_count):
for _ in range(undo_count):
turtle.undo()
screen.ontimer(square_update)
def square_update():
undo_count = draw_square()
screen.ontimer(lambda: erase_square(undo_count), 3000)
But what I'd do is make the turtle itself the square and then just move it rather than erase and (re)draw the square:
from turtle import Screen, Turtle
from random import randint
CURSOR_SIZE = 20
def draw_square():
turtle.goto(randint(-200, 200), randint(-200, 200))
def square_update():
turtle.hideturtle()
draw_square()
turtle.showturtle()
screen.ontimer(square_update, 3000)
screen = Screen()
turtle = Turtle()
turtle.hideturtle()
turtle.shape('square')
turtle.shapesize(100 / CURSOR_SIZE)
turtle.fillcolor('white')
turtle.penup()
square_update()
screen.exitonclick()
Upvotes: 1