Screen Capture Example#
The Screen Capture Example demonstrates how to capture a screen or window using
QScreenCapture. It shows a list of screens and and displays a live preview of
the selected item using a QMediaCaptureSession
and a QVideoWidget
.
There is a button to start and stop the capturing.
Application Structure#
The example consists of two custom classes. The UI and all screen capture
functionality is implemented in the class ScreenCapturePreview
. The classes
ScreenListModel
serves as model behind the QListView
. The main function
creates a ScreenCapturePreview
object, which in turn creates an instance of
QScreenCapture
, QMediaCaptureSession
and QVideoWidget
in addition
to all the UI widgets.
The list model is populated with the return values of QGuiApplication.screens()
.
When a list item is selected it is connected to the QScreenCapture
object
with QScreenCapture.setScreen()
. The QScreenCapture
object is connected
to the QMediaCaptureSession
object with
QMediaCaptureSession.setScreenCapture()
, which in turn is connected to the
QVideoWidget
object with QMediaCaptureSession.setVideoOutput()
Thus the
screen capture output is previewed in the video widget on the right hand side
of the UI.
The start/stop button calls QScreenCapture.start()
and QScreenCapture.stop()
.
A QMessageBox
pops up if the QScreenCapture.errorOccurred()
signal is emitted.
# Copyright (C) 2023 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
"""PySide6 port of the QtMultiMedia Screen Capture Example from Qt v6.x"""
import sys
from PySide6.QtWidgets import QApplication
from screencapturepreview import ScreenCapturePreview
if __name__ == "__main__":
app = QApplication(sys.argv)
screen_capture_preview = ScreenCapturePreview()
screen_capture_preview.show()
sys.exit(app.exec())
# Copyright (C) 2023 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
from PySide6.QtMultimediaWidgets import QVideoWidget
from PySide6.QtMultimedia import QScreenCapture, QMediaCaptureSession
from PySide6.QtWidgets import (QGridLayout, QLabel, QListView,
QMessageBox, QPushButton, QWidget)
from PySide6.QtGui import QGuiApplication
from PySide6.QtCore import Slot
from screenlistmodel import ScreenListModel
class ScreenCapturePreview(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self._screen_capture = QScreenCapture(self)
self._media_capture_session = QMediaCaptureSession(self)
self._video_widget = QVideoWidget(self)
self._screen_list_view = QListView(self)
self._screen_label = QLabel("Double-click screen to capture:", self)
self._video_widget_label = QLabel("QScreenCapture output:", self)
self._start_stop_button = QPushButton("Stop screencapture", self)
self._screen_list_model = ScreenListModel(self)
# Setup QScreenCapture with initial source:
self.set_screen(QGuiApplication.primaryScreen())
self._screen_capture.start()
self._media_capture_session.setScreenCapture(self._screen_capture)
self._media_capture_session.setVideoOutput(self._video_widget)
self._screen_list_view.setModel(self._screen_list_model)
grid_layout = QGridLayout(self)
grid_layout.addWidget(self._screen_label, 0, 0)
grid_layout.addWidget(self._screen_list_view, 1, 0)
grid_layout.addWidget(self._start_stop_button, 2, 0)
grid_layout.addWidget(self._video_widget_label, 0, 1)
grid_layout.addWidget(self._video_widget, 1, 1, 2, 1)
grid_layout.setColumnStretch(1, 1)
grid_layout.setRowStretch(1, 1)
grid_layout.setColumnMinimumWidth(0, 400)
grid_layout.setColumnMinimumWidth(1, 400)
self._screen_list_view.activated.connect(self.on_screen_selection_changed)
self._start_stop_button.clicked.connect(self.on_start_stop_button_clicked)
self._screen_capture.errorOccurred.connect(self.on_screen_capture_error_occured)
def set_screen(self, screen):
self._screen_capture.setScreen(screen)
self.setWindowTitle(f"Capturing {screen.name()}")
@Slot()
def on_screen_selection_changed(self, index):
self.set_screen(self._screen_list_model.screen(index))
@Slot()
def on_screen_capture_error_occured(self, error, errorString):
QMessageBox.warning(self, "QScreenCapture: Error occurred",
errorString)
@Slot()
def on_start_stop_button_clicked(self):
if self._screen_capture.isActive():
self._screen_capture.stop()
self._start_stop_button.setText("Start screencapture")
else:
self._screen_capture.start()
self._start_stop_button.setText("Stop screencapture")
# Copyright (C) 2023 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
from PySide6.QtGui import QGuiApplication
from PySide6.QtCore import QAbstractListModel, Qt, Slot
class ScreenListModel(QAbstractListModel):
def __init__(self, parent=None):
super().__init__(parent)
app = qApp
app.screenAdded.connect(self.screens_changed)
app.screenRemoved.connect(self.screens_changed)
app.primaryScreenChanged.connect(self.screens_changed)
def rowCount(self, index):
return len(QGuiApplication.screens())
def data(self, index, role):
screen_list = QGuiApplication.screens()
if role == Qt.DisplayRole:
screen = screen_list[index.row()]
w = screen.size().width()
h = screen.size().height()
dpi = screen.logicalDotsPerInch()
return f'"{screen.name()}" {w}x{h}, {dpi}DPI'
return None
def screen(self, index):
return QGuiApplication.screens()[index.row()]
@Slot()
def screens_changed(self):
self.beginResetModel()
self.endResetModel()