()后的Tkinter理解

时间:2015-03-20 21:38:40

标签: python tkinter windows-8.1 tkinter-canvas

首先,请看一下我之前的帖子:Tkinter understanding 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()正常工作!


修改

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

2 个答案:

答案 0 :(得分:0)

time in time.sleep是以秒为单位,而在after()之后是以毫秒为单位。 time.sleep(0.01)与self.canvas.after(10,self.draw)相同。如果在(2,func)之后太慢但在(1,func)之后太快你可以尝试睡眠(0.0005)然后在(1,func)之后确实给出1.5毫秒的延迟但是它几乎不可察觉。无论哪种方式,摆弄时间直到暂停是正确的。

答案 1 :(得分: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)

可以让您微调红点的位置和速度。 希望对您有帮助