Sometimes you want to make a screenshot of the window or control in a Qt app. In this article you learn how to create a window and render its contents to to a pixmap and save it as a PNG file. You also see how to support retina screens.

Save a QWidget as PNG high resolution (retina) image.

We start by creating a main window with Python and Pyside 6 that has a QLabel with some text:

window

Here is the code to create the window with the label:

import sys
from PySide6.QtWidgets import QApplication
from PySide6.QtWidgets import QMainWindow
from PySide6.QtWidgets import QStyle
from PySide6.QtWidgets import QLabel
from PySide6.QtCore import Qt
from PySide6.QtCore import QSize
from __feature__ import snake_case, true_property

class MainWindow(QMainWindow):
def __init__(self):
super().__init__()

self.geometry = QStyle.aligned_rect(Qt.LeftToRight, Qt.AlignCenter, QSize(400, 200), QApplication.primary_screen.available_geometry)
self.set_central_widget(QLabel("<center>I must have left my house at eight, because I always do.<center>"))

app = QApplication(sys.argv)
mainwindow = MainWindow()
mainwindow.show()

app.exec_()

Save QWidget as an image

Now I’d like to render the contents of the main window to an image and save it as a PNG file. The code to do this is as follows:

pixmap = QPixmap(self.size)
self.render(pixmap)
pixmap.save("test.png", "PNG", -1)

This works but has a problem. In the image below, you can see that the image is blurry:

window

Retina

To fix the blurry image, we need to enable retina resolutions. To do this, set the pixel ratio to 2 like this:

pixmap = QPixmap(QSize(800, 400))
pixmap.set_device_pixel_ratio(2)
self.render(pixmap)
pixmap.save("test.png", "PNG", -1)

Notice that the QPixmap is instantiated with twice the size of the window. When the pixel ratio is doubled, the image length and image height are also doubled.

The result is a clear, sharp image:

window

pixmap.save parameters

The save method has 3 parameters: file path, format and quality. Here are the possible values for the format:

BMP, JPG, JPEG, PNG, PPM, XBM and XPM

And the quality

Value Quality
-1 default settings
0 Small, compressed
100 Large, uncompressed

The quality value can be anything between 0 and 100

Complete example

This example creates a window, label and renders and saves the window to a high definition (retina) PNG file:

import sys
from PySide6.QtWidgets import QApplication
from PySide6.QtWidgets import QMainWindow
from PySide6.QtWidgets import QStyle
from PySide6.QtWidgets import QLabel
from PySide6.QtCore import Qt
from PySide6.QtGui import QPixmap
from PySide6.QtCore import QSize
from __feature__ import snake_case, true_property


class MainWindow(QMainWindow):
def __init__(self):
super().__init__()

self.geometry = QStyle.aligned_rect(Qt.LeftToRight, Qt.AlignCenter, QSize(400, 200), QApplication.primary_screen.available_geometry)
self.set_central_widget(QLabel("<center>I must have left my house at eight, because I always do.<center>"))
pixmap = QPixmap(QSize(800, 400))
pixmap.set_device_pixel_ratio(2)
self.render(pixmap)
pixmap.save("test.png", "PNG", -1)


app = QApplication(sys.argv)
mainwindow = MainWindow()
mainwindow.show()

app.exec_()

window

Written by Loek van den Ouweland on 2021-01-29.
Questions regarding this artice? You can send them to the address below.