aboutsummaryrefslogtreecommitdiffstats
path: root/examples/multimedia/screencapture/screencapturepreview.py
diff options
context:
space:
mode:
Diffstat (limited to 'examples/multimedia/screencapture/screencapturepreview.py')
-rw-r--r--examples/multimedia/screencapture/screencapturepreview.py162
1 files changed, 162 insertions, 0 deletions
diff --git a/examples/multimedia/screencapture/screencapturepreview.py b/examples/multimedia/screencapture/screencapturepreview.py
new file mode 100644
index 000000000..c7e0c596a
--- /dev/null
+++ b/examples/multimedia/screencapture/screencapturepreview.py
@@ -0,0 +1,162 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from enum import Enum, auto
+
+from PySide6.QtMultimediaWidgets import QVideoWidget
+from PySide6.QtMultimedia import (QCapturableWindow, QMediaCaptureSession,
+ QScreenCapture, QWindowCapture)
+from PySide6.QtWidgets import (QGridLayout, QLabel, QListView,
+ QMessageBox, QPushButton, QWidget)
+from PySide6.QtGui import QAction, QGuiApplication
+from PySide6.QtCore import QItemSelection, Qt, Slot
+
+from screenlistmodel import ScreenListModel
+from windowlistmodel import WindowListModel
+
+
+class SourceType(Enum):
+ Screen = auto()
+ Window = auto()
+
+
+class ScreenCapturePreview(QWidget):
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+ self._source = SourceType.Screen
+
+ 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("Select screen to capture:", self)
+ self._video_widget_label = QLabel("Capture output:", self)
+ self._start_stop_button = QPushButton(self)
+ self._status_label = QLabel(self)
+
+ self._screen_list_model = ScreenListModel(self)
+
+ # Setup QScreenCapture with initial source:
+ self.setScreen(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)
+
+ self._window_list_view = QListView(self)
+ self._window_capture = QWindowCapture(self)
+ self._media_capture_session.setWindowCapture(self._window_capture)
+ self._window_label = QLabel("Select window to capture:", self)
+
+ self._window_list_model = WindowListModel(self)
+ self._window_list_view.setModel(self._window_list_model)
+ update_action = QAction("Update windows List", self)
+ update_action.triggered.connect(self._window_list_model.populate)
+ self._window_list_view.addAction(update_action)
+ self._window_list_view.setContextMenuPolicy(Qt.ActionsContextMenu)
+
+ 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, 4, 0)
+ grid_layout.addWidget(self._video_widget_label, 0, 1)
+ grid_layout.addWidget(self._video_widget, 1, 1, 4, 1)
+ grid_layout.addWidget(self._window_label, 2, 0)
+ grid_layout.addWidget(self._window_list_view, 3, 0)
+ grid_layout.addWidget(self._status_label, 5, 0, 1, 2)
+
+ grid_layout.setColumnStretch(1, 1)
+ grid_layout.setRowStretch(1, 1)
+ grid_layout.setColumnMinimumWidth(0, 400)
+ grid_layout.setColumnMinimumWidth(1, 400)
+ grid_layout.setRowMinimumHeight(3, 1)
+
+ selection_model = self._screen_list_view.selectionModel()
+ selection_model.selectionChanged.connect(self.on_current_screen_selection_changed)
+ selection_model = self._window_list_view.selectionModel()
+ selection_model.selectionChanged.connect(self.on_current_window_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,
+ Qt.QueuedConnection)
+ self._window_capture.errorOccurred.connect(self.on_window_capture_error_occured,
+ Qt.QueuedConnection)
+ self.update_active(SourceType.Screen, True)
+
+ @Slot(QItemSelection)
+ def on_current_screen_selection_changed(self, selection):
+ self.clear_error_string()
+ indexes = selection.indexes()
+ if indexes:
+ self._screen_capture.setScreen(self._screen_list_model.screen(indexes[0]))
+ self.update_active(SourceType.Screen, self.is_active())
+ self._window_list_view.clearSelection()
+ else:
+ self._screen_capture.setScreen(None)
+
+ @Slot(QItemSelection)
+ def on_current_window_selection_changed(self, selection):
+ self.clear_error_string()
+ indexes = selection.indexes()
+ if indexes:
+ window = self._window_list_model.window(indexes[0])
+ if not window.isValid():
+ m = "The window is no longer valid. Update the list of windows?"
+ answer = QMessageBox.question(self, "Invalid window", m)
+ if answer == QMessageBox.Yes:
+ self.update_active(SourceType.Window, False)
+ self._window_list_view.clearSelection()
+ self._window_list_model.populate()
+ return
+ self._window_capture.setWindow(window)
+ self.update_active(SourceType.Window, self.is_active())
+ self._screen_list_view.clearSelection()
+ else:
+ self._window_capture.setWindow(QCapturableWindow())
+
+ @Slot(QWindowCapture.Error, str)
+ def on_window_capture_error_occured(self, error, error_string):
+ self.set_error_string("QWindowCapture: Error occurred " + error_string)
+
+ @Slot(QScreenCapture.Error, str)
+ def on_screen_capture_error_occured(self, error, error_string):
+ self.set_error_string("QScreenCapture: Error occurred " + error_string)
+
+ def set_error_string(self, t):
+ self._status_label.setStyleSheet("background-color: rgb(255, 0, 0);")
+ self._status_label.setText(t)
+
+ def clear_error_string(self):
+ self._status_label.clear()
+ self._status_label.setStyleSheet("")
+
+ @Slot()
+ def on_start_stop_button_clicked(self):
+ self.clear_error_string()
+ self.update_active(self._source_type, not self.is_active())
+
+ def update_start_stop_button_text(self):
+ active = self.is_active()
+ if self._source_type == SourceType.Window:
+ m = "Stop window capture" if active else "Start window capture"
+ self._start_stop_button.setText(m)
+ elif self._source_type == SourceType.Screen:
+ m = "Stop screen capture" if active else "Start screen capture"
+ self._start_stop_button.setText(m)
+
+ def update_active(self, source_type, active):
+ self._source_type = source_type
+ self._screen_capture.setActive(active and source_type == SourceType.Screen)
+ self._window_capture.setActive(active and source_type == SourceType.Window)
+
+ self.update_start_stop_button_text()
+
+ def is_active(self):
+ if self._source_type == SourceType.Window:
+ return self._window_capture.isActive()
+ if self._source_type == SourceType.Screen:
+ return self._screen_capture.isActive()
+ return False