4

首先在这里看一下我之前的帖子:Tkinter理解mainloop

在遵循那里的建议之后,在 GUI 编程中,必须不惜一切代价避免无限循环,以保持小部件对用户输入的响应。

而不是使用:

while 1:
    ball.draw()
    root.update()
    time.sleep(0.01)

self.canvas.after(1, self.draw)我在我的draw()函数内部管理使用。

所以我的代码现在看起来像这样:

# Testing skills in game programming

from Tkinter import *

root = Tk()
root.title("Python game testing")
root.resizable(0, 0)
root.wm_attributes("-topmost", 1)

canvas = Canvas(root, width=500, height=400, bd=0, highlightthickness=0)
canvas.pack()
root.update()

class Ball:
    def __init__(self, canvas, color):
        self.canvas = canvas
        self.id = canvas.create_oval(10, 10, 25, 25, fill=color)
        self.canvas.move(self.id, 245, 100)

        self.canvas_height = canvas.winfo_height()
        self.x = 0
        self.y = -1

    def draw(self):
        self.canvas.move(self.id, self.x, self.y)

        pos = self.canvas.coords(self.id)
        if pos[1] <= 0:
            self.y = 1
        if pos[3] >= self.canvas_height:
            self.y = -1

        self.canvas.after(2, self.draw)


ball = Ball(canvas, "red")
ball.draw()

root.mainloop()

但是,里面的时间self.canvas.after()不能正常工作......如果设置为 1 它非常快!如果设置为 10、5 甚至 2,那就太慢了!在我的代码中使用上述while循环时我没有遇到这个问题,time.sleep()因为它应该正常工作!


编辑:

我现在可以报告 Tkinter 的 after 函数内部的时间在我的 Windows 8.1 平板电脑和我的 Windows 8.1 笔记本电脑中无法正常工作,而在同一台笔记本电脑中通过虚拟机运行 Ubuntu 时它确实可以正常工作。

4

2 回答 2

0

time.sleep 中的时间以秒为单位,而 after() 中的时间以毫秒为单位。time.sleep(0.01) 与 self.canvas.after(10, self.draw) 相同。如果 after(2, func) 太慢但 after(1, func) 太快,那么您可以尝试 sleep(0.0005) 然后 after(1, func) 确实会延迟 1.5 毫秒,但几乎不会引起注意。无论哪种方式,摆弄时间,直到暂停是正确的。

于 2015-08-25T11:37:38.730 回答
0

对象(画布)的速度和时钟/循环速度应该被视为两个不同的东西,恕我直言。因此,您可以在 2ms 甚至更大(如 10...25...)后离开循环。

...
self.canvas.after(2, self.draw)
... # loop this after 2 ms.

同时,根据“多少像素”改变速度:

pos = self.canvas.coords(self.id)
    if pos[1] <= 0:
        self.y = 20
    if pos[3] >= self.canvas_height:
        self.y = -20

所以调整这些值,并且:

self.canvas.move(self.id, 245, 100)

可以让您微调红点的位置和速度。希望能帮助到你

于 2019-08-29T16:54:57.243 回答