【发布时间】:2017-12-16 23:51:20
【问题描述】:
我决定创建一个在 Tkinter 中轻松显示动画 gif 的类,它确实有效,但动态收集所有帧的过程几乎总是需要大量时间,并且在完成之前阻止其他任何事情发生。我想知道是否有任何方法可以加快速度或更有效的方式来做同样的事情。
这是该类的代码:
from tkinter import *
class animation:
def __init__(self,*args,**kwargs):
self.root=args[0]
self.label=Label(self.root)
self.label.grid()
self.image=kwargs["image"]
try:
self.delay=kwargs["delay"]
except KeyError:
self.delay=20
self.frames=[]
x=0
while True:
try:
img=PhotoImage(file=self.image,
format="gif -index {}".format(x))
self.frames.append(img)
x+=1
except:
break
def animate(self,y):
try:
self.label.configure(image=self.frames[y])
self.root.after(self.delay,lambda:self.animate(y+1))
except IndexError:
self.label.configure(image=self.frames[0])
self.root.after(self.delay,lambda:self.animate(1))
下面是它的使用方法:
from tkinter import *
from modules.animation import animation
root=Tk()
cosmog=animation(root,image="cosmog.gif").animate(0)
cosmoem=animation(root,image="cosmoem.gif").animate(0)
lunala=animation(root,image="lunala.gif").animate(0)
root.mainloop()
【问题讨论】:
-
也许在你启动 tkinter 之前创建一个读取所有图像的类。或者使用线程读取文件。
-
它不会有太大帮助,但是您应该加载一次图像,然后将所有帧拉出,而不是从 HDD 为每一帧加载图像。 Here's how I did that。另外,请注意创建 tkinter 小部件的正确方法:通过子类化当前小部件。这样,您就可以将其视为代码中的任何其他小部件(pack、grid、tkraise 等)。
-
FWIW,您可以使用
self.root.after(self.delay,lambda:self.animate(1))而不是self.root.after(self.delay, self.animate, 1) -
感谢大家的帮助