Moving balls in Tkinter Canvas Moving balls in Tkinter Canvas tkinter tkinter

Moving balls in Tkinter Canvas


You should never put an infinite loop inside a GUI program -- there's already an infinite loop running. If you want your balls to move independently, simply take out the loop and have the move_ball method put a new call to itself on the event loop. With that, your balls will continue to move forever (which means you should put some sort of check in there to prevent that from happening)

I've modified your program slightly by removing the infinite loop, slowing down the animation a bit, and also using random values for the direction they move. All of that changes are inside the move_ball method.

from Tkinter import *from random import randintclass Ball:    def __init__(self, canvas, x1, y1, x2, y2):        self.x1 = x1        self.y1 = y1        self.x2 = x2        self.y2 = y2        self.canvas = canvas        self.ball = canvas.create_oval(self.x1, self.y1, self.x2, self.y2, fill="red")    def move_ball(self):        deltax = randint(0,5)        deltay = randint(0,5)        self.canvas.move(self.ball, deltax, deltay)        self.canvas.after(50, self.move_ball)# initialize root Window and canvasroot = Tk()root.title("Balls")root.resizable(False,False)canvas = Canvas(root, width = 300, height = 300)canvas.pack()# create two ball objects and animate themball1 = Ball(canvas, 10, 10, 30, 30)ball2 = Ball(canvas, 60, 60, 80, 80)ball1.move_ball()ball2.move_ball()root.mainloop()


This function seems to be the culprit

def move_ball(self):    while True:        self.canvas.move(self.ball, 2, 1)        self.canvas.after(20)        self.canvas.update()

You deliberately put yourself in an infinite loop when you call it.

ball1.move_ball()    # gets called, enters infinite loopball2.move_ball()    # never gets called, because code is stuck one line above


Its only moving one because the program reads only one variable at a time. If you set the program to read when the ball gets to a certain spot, say the end of the canvas, you could then code the program to read the next line and trigger the second ball to move. But, this will only move one at a time.

Your program is literally stuck on the line:

ball1.move_ball()

And it will never get to line:

ball2.move_ball()

Because there isn't a limit to where the loop should end.

Otherwise, the answer by "sundar nataraj" will do it.