Tkinter canvas not updating in an infinite loop
There are a number of issues with your code. One big one was the way you were updating the position of the existing canvas objects. The move()
method needs to know the amount of movement (change in x and y value), not the new absolute position.
When I fixed that it turned out that the velocities were too big, so I reduced them to only be 10% of the values you had.
Another problem was with the way the ObjectHolder
class was implemented. For one thing, the moveobject()
method had no self
argument, which it should have been using instead of having an object
argument. You should probably also rename the method simply move()
.
The code below runs and does animate the movement.
import tkinter as tkclass ObjectHolder: def __init__(self, pos, velocity, radius, id): self.id = id # the id of the canvas shape self.pos = pos # the position of the object self.r = radius # the radius of incluence of the object self.velocity = velocity # the velocity of the object def moveobject(self): x, y = self.pos dx, dy = self.velocity self.pos = (x + dx, y + dy) canvas.move(self.id, dx, dy) # Amount of movement, not new position.class App(): def __init__(self, canvas): self.canvas = canvas self.objects = [] for i in range(0, 2): position = ((i+1)*100, (i+1)*100)# velocity = (-(i+1)*10, -(i+1)*10) velocity = (-(i+1), -(i+1)) # Much slower speed... radius = (i + 1) * 20 x1 = position[0]-radius y1 = position[1]-radius x2 = position[0]+radius y2 = position[1]+radius id = canvas.create_oval(x1, y1, x2, y2) self.objects.append(ObjectHolder(position, velocity, radius, id)) self.simulation(self.objects) def simulation(self, objects): for object in objects: # this moves each object object.moveobject() # This part doesn't work. It is supposed to update the canvas # and repeat forever.# self.canvas.update() # Not needed.# root.update() # Not needed. self.canvas.after(50, self.simulation, objects)root = tk.Tk()canvas = tk.Canvas(root, width=800, height=600, bg="light blue")canvas.pack()app = App(canvas)root.mainloop() # Added.