简体   繁体   中英

Python turtle draw filled irregular polygon based on user clicks

I would like to make a program that creates a turtle window that the user can click 4 times to create an irregular polygon. It will automatically go back to the starting point after the 4th click to make sure that it is properly closed. That much works great, but the problem is that I would like to have it filled in as well, which I can't get to work.

import turtle


class TrackingTurtle(turtle.Turtle):
    """ A custom turtle class with the ability to go to a mouse
    click location and keep track of the number of clicks """

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.count = 0

    def goto_mouse(self, x, y):
        """ Go to the given (x, y) coordinates, or go back
        to the starting place after the 4th click """
        if self.count <= 4:
            self.goto(x, y)
            self.count += 1
            if self.count == 4:
                self.goto(0, 0)
                turtle.done()


if __name__ == "__main__":
    turtle.setup(1080, 720)

    wn = turtle.Screen()
    wn.title("Polygon Fun")

    turt = TrackingTurtle()
    turt.hideturtle()

    turt.fillcolor("#0000ff")
    turt.begin_fill()
    turtle.onscreenclick(alex.goto_mouse)
    
    turt.end_fill()

    wn.mainloop()

Example output

I would like the above output to be filled in blue, but as you can see it's not. Is this possible with the turtle module? If so what might I change to fix it? Thanks in advance for your time and help!

You're pretty close. The misunderstanding seems to be thinking that onscreenclick blocks until the shape is done, then end_fill() runs. Actually, onscreenclick returns immediately after registering the click handler, then .end_fill() runs before any clicks have occurred or the turtle main loop runs. By the time the user starts clicking, the fill has long been closed.

The solution is to move the .end_fill() call to the if self.count == 4: block.

Since I'm not a fan of inheriting Turtle , here's a similar, minimal example that uses a closure but should be readily adaptable to your use case.

import turtle

def track_polygon(sides=5):
    def goto_mouse(x, y):
        nonlocal clicks

        if clicks < sides - 1:
            turtle.goto(x, y)
            clicks += 1

            if clicks >= sides - 1:
                turtle.goto(0, 0)
                turtle.end_fill()
                turtle.exitonclick()

    clicks = 0
    turtle.begin_fill()
    turtle.onscreenclick(goto_mouse)

track_polygon()
turtle.mainloop()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM