You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python tkinter的canvas画布中放置可正常播放的GIF动图?

Tkinter Canvas播放GIF动图的实现方法

tkinter默认自带的PhotoImage仅会加载GIF的第一帧,所以直接放置会显示为静态图。你需要手动读取GIF的所有帧、定时切换画布上的显示内容来实现动画播放,具体实现方案如下:

实现思路

  • 用Pillow库读取GIF的全部帧,存入列表做持久化引用,避免被Python垃圾回收机制清除
  • 在canvas上创建图像控件,初始加载第一帧
  • 写帧切换函数,通过after()方法定时更新canvas上的图像资源,循环播放所有帧

可运行示例代码

import tkinter as tk
# 需提前安装Pillow依赖:pip install pillow
from PIL import Image, ImageTk

# 初始化窗口和画布
root = tk.Tk()
root.title("Canvas播放GIF示例")
canvas = tk.Canvas(root, width=500, height=400)
canvas.pack()

# 加载GIF所有帧
gif_file = "替换为你的GIF文件路径.gif"
gif_obj = Image.open(gif_file)
frame_list = []
# 循环读取所有帧
try:
    while True:
        frame_list.append(ImageTk.PhotoImage(gif_obj.copy()))
        gif_obj.seek(len(frame_list))
except EOFError:
    # 读取到GIF最后一帧时自动结束循环
    pass

# 初始化帧索引和canvas图像元素
frame_index = 0
gif_canvas_item = canvas.create_image(250, 200, image=frame_list[0])

def refresh_frame():
    global frame_index
    # 切换下一帧,超过总帧数则回到第一帧循环
    frame_index = (frame_index + 1) % len(frame_list)
    # 更新画布上的图像
    canvas.itemconfig(gif_canvas_item, image=frame_list[frame_index])
    # 按间隔时间递归调用,可修改毫秒值调整播放速度,也可读取gif_obj.info['duration']使用原GIF间隔
    root.after(50, refresh_frame)

# 启动动画
refresh_frame()

root.mainloop()

注意事项

  • 不要使用tkinter原生PhotoImage加载GIF,对多帧资源的支持存在缺陷,必须使用Pillow库的ImageTk.PhotoImage处理
  • 所有帧必须存入全局变量/类属性的列表中,不能仅在局部函数内临时存储,否则图像会被回收导致显示空白
  • 如果需要和原GIF播放速度一致,可以把after()的50替换为gif_obj.info.get('duration', 50),直接读取GIF自带的帧间隔参数

内容的提问来源于stack exchange,提问作者Baz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 05:39:03