与Tkinter一起在Python中播放动画GIF



我想使用python3和tkinter创建虚拟宠物样式游戏。到目前为止,我有了主窗口,并已经开始放上标签,但是我遇到的问题是播放动画GIF。我在这里搜索并找到了一些答案,但是他们不断提出错误。我发现的结果具有GIF的索引位置,使用PhotoImage继续穿过一定范围。

    # Loop through the index of the animated gif
frame2 = [PhotoImage(file='images/ball-1.gif', format = 'gif -index %i' %i) for i in range(100)]
def update(ind):
    frame = frame2[ind]
    ind += 1
    img.configure(image=frame)
    ms.after(100, update, ind)
img = Label(ms)
img.place(x=250, y=250, anchor="center")
ms.after(0, update, 0)
ms.mainloop()

当我用" pyhton3 main.py"在终端运行它时,我会收到以下错误:

_tkinter.tclerror:此索引没有图像数据

我在忽略或完全忽略什么?

这是指向GITHUB存储库的链接以查看完整项目:virtpet_python

预先感谢!

错误意味着您尝试加载100帧,但GIF的范围少。

tkinter中的动画gif是众所周知的。我一岁时就写了这个代码,您可以从中偷走,但除了小gif外,其他任何东西都会变得很糟糕:

import tkinter as tk
from PIL import Image, ImageTk
from itertools import count
class ImageLabel(tk.Label):
    """a label that displays images, and plays them if they are gifs"""
    def load(self, im):
        if isinstance(im, str):
            im = Image.open(im)
        self.loc = 0
        self.frames = []
        try:
            for i in count(1):
                self.frames.append(ImageTk.PhotoImage(im.copy()))
                im.seek(i)
        except EOFError:
            pass
        try:
            self.delay = im.info['duration']
        except:
            self.delay = 100
        if len(self.frames) == 1:
            self.config(image=self.frames[0])
        else:
            self.next_frame()
    def unload(self):
        self.config(image="")
        self.frames = None
    def next_frame(self):
        if self.frames:
            self.loc += 1
            self.loc %= len(self.frames)
            self.config(image=self.frames[self.loc])
            self.after(self.delay, self.next_frame)
root = tk.Tk()
lbl = ImageLabel(root)
lbl.pack()
lbl.load('ball-1.gif')
root.mainloop()

首先,您需要知道GIF文件的最后范围是什么。因此,通过更改i的不同值,您将得到它。对于我的病情为31。然后只需要放置条件。

from tkinter import *
root = Tk()
frames = [
    PhotoImage(file="./images/play.gif", format="gif -index %i" % (i))
    for i in range(31)
]
def update(ind):
    frame = frames[ind]
    ind += 1
    print(ind)
    if ind > 30:  # With this condition it will play gif infinitely
        ind = 0
    label.configure(image=frame)
    root.after(100, update, ind)
label = Label(root)
label.pack()
root.after(0, update, 0)
root.mainloop()

一种非常简单的方法是使用多线程。

要在tkinter窗口中无限运行GIF,您应该按照以下内容:

  1. 创建一个运行gif的函数。
  2. 将您的代码运行在函数内部的while True中运行GIF。
  3. 创建一个线程以运行该功能。
  4. 在程序的主要流程中运行root.mainloop()
  5. 使用time.sleep()控制动画的速度。

请参阅下面的代码:

i=0
ph = ImageTk.PhotoImage(Image.fromarray(imageframes[i]))
imglabel=Label(f2,image=ph)
imglabel.grid(row=0,column=0)
def runthegif(root,i):
    
    while True:
        i = i + 7
        i= i % 150
        
        ph=ImageTk.PhotoImage(PhotoImage(file='images/ball.gif',format='gif -index %i' %i))
        imagelabel=Label(f2,image=ph)
        imagelabel.grid(row=0,column=0)
        time.sleep(0.1)
    

t1=threading.Thread(target=runthegif,args=(root,i))
t1.start()

root.mainloop()

最新更新