Reputation: 19
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
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
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