首先,请看一下我之前的帖子: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的同一台笔记本电脑中它确实有效。
答案 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)
可以让您微调红点的位置和速度。 希望对您有帮助