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

如何将Qt Widget快照存入变量?并导出动态绘图为视频

Qt Widget动画绘图导出为视频的完整方案

一、将PyQtGraph绘图快照存入变量(无需保存到文件)

PyQtGraph的ImageExporter底层依赖Qt的QImage实现渲染,我们可以绕过文件存储逻辑,直接获取渲染后的图像对象,再转换为Pillow图像或bytearray:

方法1:基于PyQtGraph Exporter获取图像

import pyqtgraph as pg
from pyqtgraph.exporters import ImageExporter
from PIL import Image

plt = pg.plot([1, 5, 2, 4, 3])
exporter = ImageExporter(plt.plotItem)

# 自定义导出尺寸(可选,默认使用Widget原尺寸)
exporter.parameters()['width'] = plt.width()
exporter.parameters()['height'] = plt.height()

# 直接获取QImage对象
qimage = exporter.exportToImage()

# 转换为Pillow图像
pil_img = Image.fromqimage(qimage)
# 转换为PNG格式的bytearray
png_bytes = bytes(qimage.saveToData())

方法2:通用Qt Widget截图(适用于所有Qt控件)

如果不限于PyQtGraph,所有Qt Widget都可以用内置的grab()方法直接截图:

from PyQt5.QtWidgets import QApplication
import pyqtgraph as pg
from PIL import Image

app = QApplication([])
plt = pg.plot([1, 5, 2, 4, 3])

# 对Widget直接截图
qimage = plt.grab()
# 转Pillow图像
pil_img = Image.fromqimage(qimage)
# 转bytearray
png_bytes = bytes(qimage.saveToData())

二、捕获动画的帧序列

要捕获动态变化的Widget帧,需要在动画更新的时机触发截图,两种常见实现方式:

方式1:定时捕获(适合周期性动画)

import pyqtgraph as pg
from PyQt5.QtCore import QTimer
from PIL import Image

app = QApplication([])
plt = pg.plot()
data = [1, 5, 2, 4, 3]
current_idx = 0
frame_list = []

def update_and_capture():
    global current_idx
    # 更新绘图(模拟动画)
    current_idx = (current_idx + 1) % len(data)
    plt.plot([current_idx, data[current_idx]], clear=True)
    
    # 捕获当前帧
    qimage = plt.grab()
    frame_list.append(Image.fromqimage(qimage))

# 每100ms更新一次(对应10fps)
timer = QTimer()
timer.timeout.connect(update_and_capture)
timer.start(100)

# 运行5秒后停止捕获
QTimer.singleShot(5000, timer.stop)

app.exec_()

方式2:绘图更新时捕获(适合自定义实时动画)

如果你的动画是通过PlotDataItem实时更新,可在更新回调中嵌入捕获逻辑:

import pyqtgraph as pg
from PyQt5.QtCore import QTimer
import numpy as np
from PIL import Image

app = QApplication([])
plt = pg.plot()
curve = plt.plot()
x = np.linspace(0, 10, 100)
current_t = 0
frame_list = []

def update_curve_and_capture():
    global current_t
    current_t += 0.1
    # 更新曲线数据(模拟正弦波动画)
    curve.setData(x, np.sin(x + current_t))
    
    # 捕获当前帧
    qimage = plt.grab()
    frame_list.append(Image.fromqimage(qimage))

# 每50ms更新一次(对应20fps)
timer = QTimer()
timer.timeout.connect(update_curve_and_capture)
timer.start(50)

# 运行3秒后停止
QTimer.singleShot(3000, timer.stop)

app.exec_()

三、将帧序列合成为视频

用MoviePy快速合成(推荐)

安装依赖:pip install moviepy

from moviepy.editor import ImageSequenceClip

# 设置帧率(需和捕获时的帧率一致)
fps = 10
# 合成视频并保存
clip = ImageSequenceClip(frame_list, fps=fps)
clip.write_videofile("animation.mp4", codec="libx264")

用OpenCV精细控制

安装依赖:pip install opencv-python

import cv2
import numpy as np

fps = 10
width, height = frame_list[0].size
# 初始化视频写入器
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
video_writer = cv2.VideoWriter("animation.mp4", fourcc, fps, (width, height))

for frame in frame_list:
    # Pillow图像转OpenCV格式(RGB转BGR)
    cv_frame = cv2.cvtColor(np.array(frame), cv2.COLOR_RGB2BGR)
    video_writer.write(cv_frame)

video_writer.release()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 05:03:36