1

I'm trying to write a program that allows me to plot some simple coordinates using the turtle module and to make it more user friendly I wanted display a cross every time the user pressed the left mouse button to plot a point. For some reason the last bit of the cross() function ie. the last line of the cross won't draw or come up until the left mouse button is pressed again. I'm really confused as to why this is happening because the code is definitely being executed. Any help would be greatly appreciated!


wn = t.Screen()
wn.title("graph")
wn.setup(width=600, height=600)
wn.tracer(0)
wn.update()

pen = t.Turtle()
pen.color("black")
pen.shape("classic")
pen.goto(0, 0)
pen.ht()

x = 10
y = 10

def cross(x, y):
    print(x, y)
    pen.pensize(2.5)
    pen.pu()
    pen.goto(x, y)
    pen.pd()
    pen.seth(225)
    pen.color("red")
    pen.fd(50)
    pen.color("black")

    pen.pu()
    pen.goto(x, y)
    pen.pd()
    pen.left(180)
    pen.fd(50)

    pen.pu()
    pen.goto(x, y)
    pen.seth(315)
    pen.pd()
    pen.color("green")
    pen.fd(50)

    pen.pu()
    pen.goto(x, y)
    pen.left(180)
    pen.pd()
    pen.color("yellow")
    pen.fd(50) #for some reason this is not being done
    print("now")

cross(x, y)

while True:
    wn.update()
    wn.onscreenclick(cross)
    wn.mainloop()

1 Answer 1

1

This code indicates a basic misunderstanding of what onscreenclick() and mainloop() do:

while True:
    wn.update()
    wn.onscreenclick(cross)
    wn.mainloop()

Let's rework the code to use these methods correctly, and fix the problem:

from turtle import Screen, Pen

def cross(x, y):
    screen.onclick(None)  # disable handler inside handler

    pen.penup()
    pen.goto(x, y)
    pen.pendown()
    pen.setheading(225)
    pen.color('red')
    pen.forward(50)

    pen.penup()
    pen.goto(x, y)
    pen.pendown()
    pen.left(180)
    pen.color('black')
    pen.forward(50)

    pen.penup()
    pen.goto(x, y)
    pen.seth(315)
    pen.pendown()
    pen.color('green')
    pen.forward(50)

    pen.penup()
    pen.goto(x, y)
    pen.left(180)
    pen.pendown()
    pen.color('yellow')
    pen.forward(50)

    screen.update()
    screen.onclick(cross)  # reenable handler on exit

screen = Screen()
screen.title("graph")
screen.setup(width=600, height=600)
screen.tracer(0)

pen = Pen()
pen.hideturtle()
pen.color('black')
pen.pensize(2.5)

x, y = 10, 10

screen.onclick(cross)

cross(x, y)

screen.mainloop()

Generally, I would avoid using tracer() and update() until your code is basically working. Putting them in from the start makes your code harder to debug.

Sign up to request clarification or add additional context in comments.

4 Comments

Hey thanks for taking the time to help me out! The solution worked but I have a couple questions if you don't mind. What does disabling the handler at the beginning and enabling it at the end of the function do? Also is there a particular reason for defining objects like the "screen" after the function? Lastly, I was under the impression that a program could not loop by itself, ie. it runs through the code once and is finished. That's why I added the "while True" loop. Is this not the case? Could you explain how it loops without a specific loop. Thanks again so much for your initial help!
@ineedpythonhelppls, disabling the hander at the beginning, and reenabling it at the end, prevents the user from starting a new cross while you're still drawing the previous one (i.e. aggressive clickers). Prevents a faux recursion and messy graphics.
@ineedpythonhelppls, I usually define Python entities in a particular order. First imports, then constants, then functions and finally the code that uses all the above. There are exceptions.
@ineedpythonhelppls, when a turtle program calls mainloop() it hands off control to the tkinter event loop which loops constantly and checks for incoming events. By using while True: you can potentially miss incoming events.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.