warcraftisgood
warcraftisgood

Reputation: 19

How to delete a shape from canvas created by a function in tkinter python?

New to ktinker and I've met a problem that I can't find a solution to. My goal is to animate a shape and allow it to move using a function inside a while loop, and the function generates the shape while the while loop deletes and refreshes the canvas. My code look something like this:

def shape():
    global a
    a = screen.create_rectangle(x,100,x+50,200,fill = 'white')

while True:
    shape(x,y)
    x+=10
    screen.update()
    screen.delete(a)
    time.sleep(0.03)

the code successfully creates a rectangle and it moves, but the code isn't deleting the rectangles. However, the code works fine and deletes the rectangles if I'm not using a function.

Upvotes: 1

Views: 306

Answers (2)

Reblochon Masque
Reblochon Masque

Reputation: 36652

The proper way to animate objects on a tk.Canvas is different from pygame and other GUI frameworks.

tk.Canvas does not require a "blitting" process; the items do not need to be deleted, and recreated each frame. The proper approach is to move existing items, either using the tk.Canvas.move method, or the tk.Canvas.coord method. The first moves the item by a provided δx and δy, whereas the second re-positions the item to the new coordinates passed to it.

Here is an example with tk.Canvas.move:

import tkinter as tk


def shape(x):
    return screen.create_rectangle(x, 100, x+50 , 200, fill='white')


def animate(rect, dx=0, dy=0):
    screen.move(rect, dx, dy)
    screen.after(100, animate, rect, dx)


if __name__ == '__main__':

    root = tk.Tk()
    screen = tk.Canvas(root, width=400, height=400, bg='cyan')
    screen.pack()

    rect = shape(50)
    animate(rect, dx=10)

    root.mainloop()

Notice that we make use of the tk.mainloop provided by the framework, instead of a clumsy while True loop. The tk.after method is the correct approach to call a function (here animate) at regular intervals.
We also avoid the use of time.sleep which always results to problems and blocking the GUI.

Upvotes: 1

Elder Yeager
Elder Yeager

Reputation: 83

Try updating the screen after you delete the shape.

def shape():
    global a
    a = screen.create_rectangle(x,100,x+50,200,fill = 'white')

while True:
    shape(x,y)
    x+=10
    screen.update()
    screen.delete(a)
    screen.update()
    time.sleep(0.03)

Upvotes: 1

Related Questions