使用 tkinter 在 python 中播放 GIF 动画
Play an Animated GIF in python with tkinter
我想使用 python3 和 tkinter 创建一个虚拟宠物风格的游戏。到目前为止,我有主要的 window 并开始放入标签,但我遇到的问题是播放动画 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: no image data for this index
我忽略或完全遗漏了什么?
这里是 link 到 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 的不同值,你会得到 it.For 我的条件是 31。
然后只需要放 condition.So 它就会无限播放gif。
from tkinter import *
import time
import os
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 window 中无限地 运行 GIF,您应该遵循以下步骤:
- 为 运行 GIF 创建函数。
- 将您的代码放入 运行 函数内
while True
的 GIF。
- 为 运行 函数创建一个线程。
- 运行
root.mainloop()
在程序的主流程中。
- 使用
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()
我想使用 python3 和 tkinter 创建一个虚拟宠物风格的游戏。到目前为止,我有主要的 window 并开始放入标签,但我遇到的问题是播放动画 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: no image data for this index
我忽略或完全遗漏了什么?
这里是 link 到 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 的不同值,你会得到 it.For 我的条件是 31。 然后只需要放 condition.So 它就会无限播放gif。
from tkinter import *
import time
import os
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 window 中无限地 运行 GIF,您应该遵循以下步骤:
- 为 运行 GIF 创建函数。
- 将您的代码放入 运行 函数内
while True
的 GIF。 - 为 运行 函数创建一个线程。
- 运行
root.mainloop()
在程序的主流程中。 - 使用
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()