aboutsummaryrefslogtreecommitdiffstats
path: root/examples/multimedia/camera/camera.py
diff options
context:
space:
mode:
Diffstat (limited to 'examples/multimedia/camera/camera.py')
-rw-r--r--examples/multimedia/camera/camera.py218
1 files changed, 128 insertions, 90 deletions
diff --git a/examples/multimedia/camera/camera.py b/examples/multimedia/camera/camera.py
index 030840803..d2c6ab187 100644
--- a/examples/multimedia/camera/camera.py
+++ b/examples/multimedia/camera/camera.py
@@ -1,7 +1,7 @@
#############################################################################
##
-## Copyright (C) 2017 The Qt Company Ltd.
+## Copyright (C) 2021 The Qt Company Ltd.
## Contact: http://www.qt.io/licensing/
##
## This file is part of the Qt for Python examples of the Qt Toolkit.
@@ -41,104 +41,131 @@
"""PySide6 Multimedia Camera Example"""
-import os, sys
-from PySide6.QtCore import QDate, QDir, QStandardPaths, Qt, QUrl
+import os
+import sys
+from PySide6.QtCore import QDate, QDir, QStandardPaths, Qt, QUrl, Slot
from PySide6.QtGui import QAction, QGuiApplication, QDesktopServices, QIcon
from PySide6.QtGui import QImage, QPixmap
from PySide6.QtWidgets import (QApplication, QHBoxLayout, QLabel,
QMainWindow, QPushButton, QTabWidget, QToolBar, QVBoxLayout, QWidget)
-from PySide6.QtMultimedia import QCamera, QCameraImageCapture, QCameraInfo
-from PySide6.QtMultimediaWidgets import QCameraViewfinder
+from PySide6.QtMultimedia import (QCamera, QCameraImageCapture,
+ QCameraInfo, QMediaCaptureSession,
+ QMediaDevices)
+from PySide6.QtMultimediaWidgets import QVideoWidget
class ImageView(QWidget):
def __init__(self, previewImage, fileName):
super().__init__()
- self.fileName = fileName
-
- mainLayout = QVBoxLayout(self)
- self.imageLabel = QLabel()
- self.imageLabel.setPixmap(QPixmap.fromImage(previewImage))
- mainLayout.addWidget(self.imageLabel)
-
- topLayout = QHBoxLayout()
- self.fileNameLabel = QLabel(QDir.toNativeSeparators(fileName))
- self.fileNameLabel.setTextInteractionFlags(Qt.TextBrowserInteraction)
-
- topLayout.addWidget(self.fileNameLabel)
- topLayout.addStretch()
- copyButton = QPushButton("Copy")
- copyButton.setToolTip("Copy file name to clipboard")
- topLayout.addWidget(copyButton)
- copyButton.clicked.connect(self.copy)
- launchButton = QPushButton("Launch")
- launchButton.setToolTip("Launch image viewer")
- topLayout.addWidget(launchButton)
- launchButton.clicked.connect(self.launch)
- mainLayout.addLayout(topLayout)
-
+ self._file_name = fileName
+
+ main_layout = QVBoxLayout(self)
+ self._image_label = QLabel()
+ self._image_label.setPixmap(QPixmap.fromImage(previewImage))
+ main_layout.addWidget(self._image_label)
+
+ top_layout = QHBoxLayout()
+ self._file_name_label = QLabel(QDir.toNativeSeparators(fileName))
+ self._file_name_label.setTextInteractionFlags(Qt.TextBrowserInteraction)
+
+ top_layout.addWidget(self._file_name_label)
+ top_layout.addStretch()
+ copy_button = QPushButton("Copy")
+ copy_button.setToolTip("Copy file name to clipboard")
+ top_layout.addWidget(copy_button)
+ copy_button.clicked.connect(self.copy)
+ launch_button = QPushButton("Launch")
+ launch_button.setToolTip("Launch image viewer")
+ top_layout.addWidget(launch_button)
+ launch_button.clicked.connect(self.launch)
+ main_layout.addLayout(top_layout)
+
+ @Slot()
def copy(self):
- QGuiApplication.clipboard().setText(self.fileNameLabel.text())
+ QGuiApplication.clipboard().setText(self._file_name_label.text())
+ @Slot()
def launch(self):
- QDesktopServices.openUrl(QUrl.fromLocalFile(self.fileName))
+ QDesktopServices.openUrl(QUrl.fromLocalFile(self._file_name))
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
- self.cameraInfo = QCameraInfo.defaultCamera()
- self.camera = QCamera(self.cameraInfo)
- self.camera.setCaptureMode(QCamera.CaptureStillImage)
- self.imageCapture = QCameraImageCapture(self.camera)
- self.imageCapture.imageCaptured.connect(self.imageCaptured)
- self.imageCapture.imageSaved.connect(self.imageSaved)
- self.currentPreview = QImage()
+ self._capture_session = None
+ self._camera = None
+ self._camera_info = None
+ self._image_capture = None
+
+ available_cameras = QMediaDevices.videoInputs()
+ if available_cameras:
+ self._camera_info = available_cameras[0]
+ self._camera = QCamera(self._camera_info)
+ self._camera.errorOccurred.connect(self._camera_error)
+ self._image_capture = QCameraImageCapture(self._camera)
+ self._image_capture.imageCaptured.connect(self.image_captured)
+ self._image_capture.imageSaved.connect(self.image_saved)
+ self._image_capture.errorOccurred.connect(self._capture_error)
+ self._capture_session = QMediaCaptureSession()
+ self._capture_session.setCamera(self._camera)
+ self._capture_session.setImageCapture(self._image_capture)
+
+ self._current_preview = QImage()
+
+ tool_bar = QToolBar()
+ self.addToolBar(tool_bar)
+
+ file_menu = self.menuBar().addMenu("&File")
+ shutter_icon = QIcon(os.path.join(os.path.dirname(__file__),
+ "shutter.svg"))
+ self._take_picture_action = QAction(shutter_icon, "&Take Picture", self,
+ shortcut="Ctrl+T",
+ triggered=self.take_picture)
+ self._take_picture_action.setToolTip("Take Picture")
+ file_menu.addAction(self._take_picture_action)
+ tool_bar.addAction(self._take_picture_action)
- toolBar = QToolBar()
- self.addToolBar(toolBar)
+ exit_action = QAction(QIcon.fromTheme("application-exit"), "E&xit",
+ self, shortcut="Ctrl+Q", triggered=self.close)
+ file_menu.addAction(exit_action)
- fileMenu = self.menuBar().addMenu("&File")
- shutterIcon = QIcon(os.path.join(os.path.dirname(__file__),
- "shutter.svg"))
- self.takePictureAction = QAction(shutterIcon, "&Take Picture", self,
- shortcut="Ctrl+T",
- triggered=self.takePicture)
- self.takePictureAction.setToolTip("Take Picture")
- fileMenu.addAction(self.takePictureAction)
- toolBar.addAction(self.takePictureAction)
-
- exitAction = QAction(QIcon.fromTheme("application-exit"), "E&xit",
- self, shortcut="Ctrl+Q", triggered=self.close)
- fileMenu.addAction(exitAction)
-
- aboutMenu = self.menuBar().addMenu("&About")
- aboutQtAction = QAction("About &Qt", self, triggered=qApp.aboutQt)
- aboutMenu.addAction(aboutQtAction)
-
- self.tabWidget = QTabWidget()
- self.setCentralWidget(self.tabWidget)
-
- self.cameraViewfinder = QCameraViewfinder()
- self.camera.setViewfinder(self.cameraViewfinder)
- self.tabWidget.addTab(self.cameraViewfinder, "Viewfinder")
-
- if self.camera.status() != QCamera.UnavailableStatus:
- name = self.cameraInfo.description()
+ about_menu = self.menuBar().addMenu("&About")
+ about_qt_action = QAction("About &Qt", self, triggered=qApp.aboutQt)
+ about_menu.addAction(about_qt_action)
+
+ self._tab_widget = QTabWidget()
+ self.setCentralWidget(self._tab_widget)
+
+ self._camera_viewfinder = QVideoWidget()
+ self._tab_widget.addTab(self._camera_viewfinder, "Viewfinder")
+
+ if self._camera and self._camera.status() != QCamera.UnavailableStatus:
+ name = self._camera_info.description()
self.setWindowTitle(f"PySide6 Camera Example ({name})")
- self.statusBar().showMessage(f"Starting: '{name}'", 5000)
- self.camera.start()
+ self.show_status_message(f"Starting: '{name}'")
+ self._capture_session.setVideoOutput(self._camera_viewfinder)
+ self._take_picture_action.setEnabled(self._image_capture.isReadyForCapture())
+ self._image_capture.readyForCaptureChanged.connect(self._take_picture_action.setEnabled)
+ self._camera.start()
else:
self.setWindowTitle("PySide6 Camera Example")
- self.takePictureAction.setEnabled(False)
- self.statusBar().showMessage("Camera unavailable", 5000)
+ self._take_picture_action.setEnabled(False)
+ self.show_status_message("Camera unavailable")
+
+ def show_status_message(self, message):
+ self.statusBar().showMessage(message, 5000)
+
+ def closeEvent(self, event):
+ if self._camera and self._camera.status() == QCamera.ActiveStatus:
+ self._camera.stop()
+ event.accept()
- def nextImageFileName(self):
- picturesLocation = QStandardPaths.writableLocation(QStandardPaths.PicturesLocation)
- dateString = QDate.currentDate().toString("yyyyMMdd")
- pattern = f"{picturesLocation}/pyside6_camera_{dateString}_{{:03d}}.jpg"
+ def next_image_file_name(self):
+ pictures_location = QStandardPaths.writableLocation(QStandardPaths.PicturesLocation)
+ date_string = QDate.currentDate().toString("yyyyMMdd")
+ pattern = f"{pictures_location}/pyside6_camera_{date_string}_{{:03d}}.jpg"
n = 1
while True:
result = pattern.format(n)
@@ -147,26 +174,37 @@ class MainWindow(QMainWindow):
n = n + 1
return None
- def takePicture(self):
- self.currentPreview = QImage()
- self.camera.searchAndLock()
- self.imageCapture.capture(self.nextImageFileName())
- self.camera.unlock()
+ @Slot()
+ def take_picture(self):
+ self._current_preview = QImage()
+ self._image_capture.captureToFile(self.next_image_file_name())
+
+ @Slot(int, QImage)
+ def image_captured(self, id, previewImage):
+ self._current_preview = previewImage
+
+ @Slot(int, str)
+ def image_saved(self, id, fileName):
+ index = self._tab_widget.count()
+ image_view = ImageView(self._current_preview, fileName)
+ self._tab_widget.addTab(image_view, f"Capture #{index}")
+ self._tab_widget.setCurrentIndex(index)
- def imageCaptured(self, id, previewImage):
- self.currentPreview = previewImage
+ @Slot(int, QCameraImageCapture.Error, str)
+ def _capture_error(self, id, error, error_string):
+ print(error_string, file=sys.stderr)
+ self.show_status_message(error_string)
- def imageSaved(self, id, fileName):
- index = self.tabWidget.count()
- imageView = ImageView(self.currentPreview, fileName)
- self.tabWidget.addTab(imageView, f"Capture #{index}")
- self.tabWidget.setCurrentIndex(index)
+ @Slot(QCamera.Error, str)
+ def _camera_error(self, error, error_string):
+ print(error_string, file=sys.stderr)
+ self.show_status_message(error_string)
if __name__ == '__main__':
app = QApplication(sys.argv)
- mainWin = MainWindow()
- availableGeometry = app.desktop().availableGeometry(mainWin)
- mainWin.resize(availableGeometry.width() / 3, availableGeometry.height() / 2)
- mainWin.show()
+ main_win = MainWindow()
+ available_geometry = main_win.screen().availableGeometry()
+ main_win.resize(available_geometry.width() / 3, available_geometry.height() / 2)
+ main_win.show()
sys.exit(app.exec())