在Tkinter画布中移动球

2024-04-27 19:00:42 发布

您现在位置:Python中文网/ 问答频道 /正文

这是一个非常基本的程序,我想做两个移动球,但只有一个真正的移动。

我也尝试过一些变体,但无法移动第二个球;另一个相关的问题-有些人使用move(object)方法来实现此目的,而其他人则使用delete(object)方法,然后重新绘制。我应该用哪一个?为什么?

这是我的代码,它只设置/移动一个球:

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()

Tags: and方法selfmoveobjectdefcreateroot
3条回答

你不应该在GUI程序中放一个无限循环——已经有一个无限循环在运行了。如果希望球独立移动,只需取出循环,让move_ball方法在事件循环中对自身进行一个新调用。有了它,你的球会永远地移动(这意味着你应该在那里做些检查以防止这种情况发生)

我稍微修改了一下你的程序,去掉了无限循环,使动画慢了一点,还使用了随机值作为它们移动的方向。所有这些更改都在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()

这个功能似乎是罪魁祸首

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

当你调用它时,你故意将自己置于一个无限循环中。

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

因为程序一次只能读取一个变量,所以它只能移动一个变量。如果将程序设置为在球到达某个位置时读取,例如画布的末端,则可以编写程序以读取下一行并触发第二个球移动。但是,一次只能移动一个。

你的程序真的陷入了困境:

ball1.move_ball()

它永远也不会排成一行:

ball2.move_ball()

因为循环应该结束的地方没有限制。

否则,“sundar nataraj”的答案就行了。

相关问题 更多 >