Search code examples
pythontkinter

How do I stop my tkinter animation from disappearing at the end of my loop?


As the title states, how do I stop the images in an animation made in tkinter from disappearing?

I have my code here:

ballx1 = 100
bally1 = 500
speed=10

for frames in range(300):
    rectangle = s.create_rectangle(ballx1,bally1,ballx1+100,bally1+200,fill='red')
    s.update()
    sleep(0.0333)
    s.delete(rectangle)
    if(bally1 >= 600):
        speed=speed * -1
    if bally1<=0:
        speed=speed * -1
    bally1=bally1-speed

How would I prevent the screen from going black at the end of the loop?

I have attempted altering the delete line to this,

if frames<=299:
        s.delete(rectangle)

, but the screen still goes black in the end.


Solution

  • You should not create and delete the rectangle to move it. Instead create the rectangle once and just move it inside the for loop using .coords():

    # create the rectangle
    rectangle = s.create_rectangle(ballx1, bally1, ballx1+100, bally1+200, fill='red')
    
    for frame in range(300):
        s.update()
        sleep(0.0333)
        if bally1 >= 600 or bally1 <= 0:
            speed *= -1
        bally1 -= speed
        # move the rectangle
        s.coords(rectangle, ballx1, bally1, ballx1+100, bally1+200)
    

    However it is not recommended to use for loop and sleep() in a tkinter application because it will block the tkinter mainloop() from handling pending events and updates. Better use after loop instead.

    rectangle = s.create_rectangle(ballx1, bally1, ballx1+100, bally1+200, fill='red')
    
    def animation(bally, speed, n=300):
        if n >= 0:
            if bally >= 600 or bally <= 10:
                speed *= -1
            bally -= speed
            s.coords(rectangle, ballx1, bally, ballx1+100, bally+200)
            s.after(33, animation, bally, speed, n-1)
    
    # start the animation
    animation(bally1, speed)