Bolas en movimiento en Tkinter Canvas

Este es un progtwig muy básico con el que quiero hacer dos bolas en movimiento, pero solo una de ellas se mueve realmente.

He intentado algunas variaciones también, pero no puedo mover la segunda bola; otra pregunta relacionada: algunas personas usan el método de move(object) para lograr esto, mientras que otras hacen una delete(object) y luego lo vuelven a dibujar. ¿Cuál debo usar y por qué?

Este es mi código que solo está animando / moviendo una bola:

 from Tkinter import * class 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): while True: self.canvas.move(self.ball, 2, 1) self.canvas.after(20) self.canvas.update() # initialize root Window and canvas root = Tk() root.title("Balls") root.resizable(False,False) canvas = Canvas(root, width = 300, height = 300) canvas.pack() # create two ball objects and animate them ball1 = Ball(canvas, 10, 10, 30, 30) ball2 = Ball(canvas, 60, 60, 80, 80) ball1.move_ball() ball2.move_ball() root.mainloop() 

Nunca debe poner un bucle infinito dentro de un progtwig GUI – ya hay un bucle infinito ejecutándose. Si desea que sus bolas se muevan de forma independiente, simplemente move_ball el bucle y move_ball método move_ball una nueva llamada a sí mismo en el bucle de eventos. Con eso, tus bolas seguirán moviéndose para siempre (lo que significa que debes poner algún tipo de control allí para evitar que eso ocurra)

He modificado ligeramente tu progtwig eliminando el bucle infinito, reduciendo la velocidad de la animación un poco y también utilizando valores aleatorios para la dirección en la que se mueven. Todos esos cambios están dentro del método move_ball .

 from Tkinter import * from random import randint class 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 canvas root = Tk() root.title("Balls") root.resizable(False,False) canvas = Canvas(root, width = 300, height = 300) canvas.pack() # create two ball objects and animate them ball1 = Ball(canvas, 10, 10, 30, 30) ball2 = Ball(canvas, 60, 60, 80, 80) ball1.move_ball() ball2.move_ball() root.mainloop() 

Esta función parece ser la culpable

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

Te pones deliberadamente en un bucle infinito cuando lo llamas.

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

Solo se mueve uno porque el progtwig lee solo una variable a la vez. Si configura el progtwig para que lea cuando la bola llegue a un punto determinado, diga el final del canvas, podría codificar el progtwig para leer la siguiente línea y hacer que la segunda bola se mueva. Pero, esto solo se moverá de uno en uno.

Su progtwig está literalmente atascado en la línea:

ball1.move_ball()

Y nunca llegará a la línea:

ball2.move_ball()

Porque no hay un límite para el final del bucle.

De lo contrario, la respuesta de “sundar nataraj” lo hará.

intente en lugar de self.canvas.move(self.ball, 2, 1) use

 self.canvas.move(ALL, 2, 1) 

Todo esto utilizado para mover todos los objetos en el canvas.