Is there a function to save a snapshot of a qt widget in a variable?

Question:

I am trying to create a function to export an animated plot to a video format. This plot is a qt widget. I believe the first step in this is to transform a single image into a bytearray or a pillow image or something like that, but I can’t figure out how to do this. After this I think subsequent images should be saved and added together to one video.

I tried adjusting the following program which exports a single image:

import pyqtgraph as pg
import pyqtgraph.exporters

# generate something to export
plt = pg.plot([1, 5, 2, 4, 3])

# create an exporter instance, as an argument give it
# the item you wish to export
exporter = pg.exporters.ImageExporter(plt.plotItem)

# save to file
exporter.export('fileName.png')

from this website. But I couldn’t get it to store it in a variable instead of exporting it to a png file. Does anybody know how to do this, or how else to approach exporting a sequence of images of a changing qt widget?

Asked By: Rik Mulder

||

Answers:

I have made the following function to first store a snapshot of plot_widget as a QPixMap, then this is converted to a QImage, then it is turned into an pillow image. Then this list of images is turned into an mp4 file using imageio. (I could only get gifs with PIL and those were too slow for me)

import io
from PIL import Image
from PySide6.QtCore import QBuffer
from PySide6.QtWidgets import QApplication     # usecase specific
import imageio
import pyqtgraph as pg                         # usecase specific


def current_img(plot_widget):                  # returns current widget as PIL Image
    pix_map = plot_widget.grab()
    q_img = pix_map.toImage()
    buffer = QBuffer()
    buffer.open(QBuffer.ReadWrite)
    q_img.save(buffer, "PNG")
    return Image.open(io.BytesIO(buffer.data()))


app = QApplication()
plot_window = pg.PlotWidget()   # my specific usecase

filename = "file_location"
imgs = []
while len(imgs) < 120:
    imgs.append(current_img(plot_window))
    # insert code that adjusts plot_window
imageio.mimsave(f"{filename}.mp4", imgs, fps=30)

It does what I want, but since it is saving a lot of images to get decent plot quality it is very slow. So I’ll be testing other options to see if they’re faster, so if anyone knows of another (faster) way, please share.

Answered By: Rik Mulder
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.