使用 tkinter 在 Python 中播放动画 GIF

2025-03-11 08:50:00
admin
原创
65
摘要:问题描述:我想使用 python3 和 tkinter 创建一个虚拟宠物风格的游戏。到目前为止,我已经有了主窗口并开始放入标签,但我遇到的问题是播放动画 gif。我在这里搜索并找到了一些答案,但它们不断抛出错误。我发现的结果是使用 PhotoImage 的 gif 的索引位置在一定范围内继续。 # Lo...

问题描述:

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

    # 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

提前致谢!


解决方案 1:

该错误意味着您尝试加载 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()

解决方案 2:

首先,您需要知道 GIF 文件的最后范围是什么。因此,通过改变 i 的不同值,您将获得它。对于我的条件是 31。然后只需要设置条件。因此它将无限播放 gif。

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()

解决方案 3:

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

要在 Tkinter 窗口中无限运行 GIF,您应该遵循以下步骤:

  1. 创建一个函数来运行 GIF。

  2. 将运行 GIF 的代码放入while True函数内部。

  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()

解决方案 4:

我已经更新了一个答案,这是完整的代码

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):
        self.update()
        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('C:/AI/Picturse/Animation/idle_animation.gif')

root.mainloop()
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   3983  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   2747  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Freshdesk、ClickUp、nTask、Hubstaff、Plutio、Productive、Targa、Bonsai、Wrike。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在项目管理过程中面临着诸多痛点,如任务分配不...
项目管理系统   82  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Monday、TeamGantt、Filestage、Chanty、Visor、Smartsheet、Productive、Quire、Planview。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多项目经理和团队在管理复杂项目时,常...
开源项目管理工具   90  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Smartsheet、GanttPRO、Backlog、Visor、ResourceGuru、Productive、Xebrio、Hive、Quire。在当今快节奏的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在选择项目管理工具时常常面临困惑:...
项目管理系统   79  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用