Tkinter窗口无法显示视频问题求助(OpenCV+Tkinter新手)
解决Tkinter+OpenCV视频无法显示的问题
嘿,我看到你作为OpenCV和Tkinter新手,在GUI中显示视频遇到了问题,这俩工具结合的时候确实容易踩几个小坑,我来帮你搞定它!
你的代码里的核心问题
- 视频捕获对象被提前释放:你在调用
update()之后立刻执行了vid.release(),这会导致视频流还没开始读取就被关闭了,自然拿不到任何帧。 - PhotoImage对象被垃圾回收:Tkinter的
PhotoImage如果没有被持久化引用,Python的垃圾回收机制会自动销毁它,画布就没法显示图像了。
修正后的完整代码
from tkinter import * from PIL import Image, ImageTk import cv2 root = Tk() root.title("Video!") vid = cv2.VideoCapture("video.mp4") width = int(vid.get(cv2.CAP_PROP_FRAME_WIDTH)) height = int(vid.get(cv2.CAP_PROP_FRAME_HEIGHT)) def get_frame(): ret, frame = vid.read() if ret: return (ret, cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)) else: return (ret, None) def update(): ret, frame = get_frame() if ret: img = Image.fromarray(frame) photo = ImageTk.PhotoImage(image=img) # 给PhotoImage加持久引用,避免被垃圾回收 canvas.photo = photo canvas.create_image(0, 0, image=photo, anchor=NW) root.after(delay, update) def on_closing(): # 窗口关闭时释放视频资源 vid.release() root.destroy() canvas = Canvas(root, width=width, height=height) canvas.pack() delay = 15 update() # 绑定窗口关闭事件,确保资源被释放 root.protocol("WM_DELETE_WINDOW", on_closing) root.mainloop()
关键修改说明
- 调整视频资源释放时机:新增
on_closing()函数,通过root.protocol("WM_DELETE_WINDOW", on_closing)绑定窗口关闭事件,只有当用户关闭窗口时才释放vid,保证视频流在整个程序运行期间都能被读取。 - 保留PhotoImage引用:在
update()函数里把photo赋值给canvas.photo,这样Python就不会把这个对象当作垃圾回收掉,画布就能持续显示每一帧图像。 - 转换宽高为整数:
vid.get()返回的是浮点数,Tkinter的Canvas尺寸需要整数,所以加上int()转换避免潜在问题。
这样修改后,你的视频应该就能正常在Tkinter窗口里播放啦😉
内容的提问来源于stack exchange,提问作者Jovan
相关产品推荐
相关产品推荐

