python Tkinter gif循环无限增加速度

quhf5bfb  于 2023-01-01  发布在  Python
关注(0)|答案(1)|浏览(125)

我使用Tkinter和python来播放动画,它运行得很好,启动时大约是25-30 fps。但是一旦我点击标签来改变一个gif,它就开始随着每次点击而增加fps。我甚至不能确定到底是什么导致了这个问题。我尝试改变.after()函数中的超时参数并添加time.sleep()。这是Tkinter的错误吗?

from tkinter import *
from PIL import Image
import random

root = Tk()

class GifAnimation:
    def __init__(self):
        self.master = root
        self.gif_path = ""
        self.gif_label: Label = None
        self.gif_count = 0
        
        self.gifs_list = [
            "./gifs/gif1.gif",
            "./gifs/gif2.gif",
            "./gifs/gif3.gif",
            "./gifs/gif4.gif",
            "./gifs/gif5.gif"
        ]
    
    def configure(self):
        self.gif_label = Label(self.master)
        self.gif_label.pack()
        self.gif_label.bind("<Button-1>", lambda x: self.change_gif())
        
        self.gif_path = random.choice(self.gifs_list)
        self.gif_info = Image.open(self.gif_path)
        self.gif_frames = self.gif_info.n_frames
        self.gif_im = [PhotoImage(file=self.gif_path,format=f"gif -index {i}") for i in range(self.gif_frames)]
    
    def animation(self):
        self.gif_im2 = self.gif_im[self.gif_count]
        self.gif_label.configure(image=self.gif_im2)
        self.gif_count += 1
        if self.gif_count == self.gif_frames:
            self.gif_count = 0
        self.master.after(100, self.animation)
    
    def change_gif(self):
        self.gif_label.destroy() # avoid infitite label creation
        self.gif_count = 0 # reset gif frames
        self.configure() 
        self.animation()

if __name__ == '__main__':
    gif = GifAnimation()
    gif.configure()
    gif.animation()
    root.mainloop()
fnvucqvd

fnvucqvd1#

正如评论中所解释的,需要添加self.master.after_cancel()
after_cancel()函数用于停止after()函数的调度。*
self.master.after_cancel()需要after() ID(参见animations中的self.after_id)。
下面是需要修改的两个函数。

def animation(self):
    self.gif_im2 = self.gif_im[self.gif_count]
    self.gif_label.configure(image=self.gif_im2)
    self.gif_count += 1
    if self.gif_count == self.gif_frames:
        self.gif_count = 0
    self.after_id= self.master.after(100, self. Animation)

def change_gif(self):
    self.master.after_cancel(self.after_id)
    self.gif_label.destroy()  # avoid infitite label creation
    self.gif_count = 0  # reset gif frames
    self.configure()
    self. Animation()

完整工作代码:

from tkinter import *
from PIL import Image
import random

root = Tk()

class GifAnimation:
    def __init__(self):
        self.master = root
        self.gif_path = ""
        self.gif_label: Label = None
        self.gif_count = 0

        self.gifs_list = [
            r"Z:\TEMP\tabata\gif\0002.gif",
            r"Z:\TEMP\tabata\gif\0003.gif",
            r"Z:\TEMP\tabata\gif\0004.gif",
            r"Z:\TEMP\tabata\gif\0000.gif",
            r"Z:\TEMP\tabata\gif\0001.gif"
        ]

    def configure(self):
        self.gif_label = Label(self.master)
        self.gif_label.pack()
        self.gif_label.bind("<Button-1>", lambda x: self.change_gif())

        self.gif_path = random.choice(self.gifs_list)
        self.gif_info = Image.open(self.gif_path)
        self.gif_frames = self.gif_info.n_frames
        self.gif_im = [PhotoImage(
            file=self.gif_path, format=f"gif -index {i}") for i in range(self.gif_frames)]

    def animation(self):
        self.gif_im2 = self.gif_im[self.gif_count]
        self.gif_label.configure(image=self.gif_im2)
        self.gif_count += 1
        if self.gif_count == self.gif_frames:
            self.gif_count = 0
        self.after_id = self.master.after(100, self.animation)

    def change_gif(self):
        self.master.after_cancel(self.after_id)
        self.gif_label.destroy()  # avoid infitite label creation
        self.gif_count = 0  # reset gif frames
        self.configure()
        self.animation()

if __name__ == '__main__':
    gif = GifAnimation()
    gif.configure()
    gif.animation()
    root.mainloop()

相关问题