我用Tkinter搜索了一个简单的动画代码,但我发现了非常不同的例子,我无法理解编写动画的正确方法。 这是我的工作代码,用于显示一个简单的移动圆圈:
import tkinter as tk
import time
root=tk.Tk()
canvas=tk.Canvas(root,width=400,height=400)
canvas.pack()
circle=canvas.create_oval(50,50,80,80,outline="white",fill="blue")
def redraw():
canvas.after(100,redraw)
canvas.move(circle,5,5)
canvas.update()
canvas.after(100,redraw)
root.mainloop()
在这段代码中,我无法正确理解:after方法如何工作,正确放置更新和移动方法(在方法之后?),还有另一种编写动画代码的方法吗?你可以给我发另一个例子并评论代码吗? 谢谢:))
答案 0 :(得分:1)
致电update
你不应该致电canvas.update()
。作为一般经验法则,您永远不会致电update
。
如果您取消对canvas.update()
的调用,您可以使用正确的方法在tkinter程序中执行动画。
致电after
开始动画
在致电after
之前,您无需立即致电root.mainloop()
。这也适用:
...
redraw()
root.mainloop()
在这种特定情况下使用或不使用after
的选择取决于您是否希望动画立即启动(甚至可能在窗口小部件可见之前),或者您希望在短暂延迟后发生(可能在小部件可见之后)
after
如何运作
mainloop
只不过是一个无限循环,用于检查事件队列中的事件。当它找到一个事件时,它会将其从列表中弹出并处理它。 after
只不过是在100毫秒内发出"请求在队列中添加新事件"。当时间限制到期时,会向队列添加一个事件,该事件实际上表示"运行此命令"。下次循环检查事件时,它会看到此事件,将其从队列中拉出,然后运行该命令。
当您从after
调用的方法中调用after
时,您实际上已经说过"等待100毫秒并再次执行#34;,创建一个无限循环。如果您在移动对象之前将呼叫转移到after
,则表示"每100ms运行此功能"。如果你把它放在'之后说"在最后一次运行后100毫秒运行这个功能"。差异非常微妙,通常不会被察觉,除非你的功能需要很长时间才能运行。
答案 1 :(得分:0)
我的代码是:
from tkinter import *
import time
tk = Tk()
płótno = Canvas(tk, width=500, height=500)
płótno.pack()
płótno.create_polygon(10,10,10,70,70,10,fill="blue",outline="black")
for x in range(0,51):
płótno.move(1,5,0)
płótno.update()
rest(0.05)
płótno表示画布