如何在 PyQt5 中使用 QCamera 单击照片?

How to click a photo using QCamera in PyQt5?

PyQT5 QCamera 不点击照片


我尝试参考他们的官方 PyQt5 QCamera 文档,但理解不多。

  1. 我创建了一个带有按钮的主窗口
  2. 点击按钮,执行 clickphoto 函数
  3. clickphoto 函数仅在可用相机列表长度 > 0 时运行以捕获图像,否则打印错误
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtMultimedia import *
from PyQt5.QtMultimediaWidgets import *
import os
class Ui_MainWindow(object):
    def clickphoto(self):
        print("clickphoto Called !")
        available_cameras = QCameraInfo.availableCameras()
        if len(available_cameras)>0:
            print(available_cameras[0].description())
            try:
                camera = QCamera(available_cameras[0])
                camera.setCaptureMode(QCamera.CaptureStillImage)
                camera.start()
                capture = QCameraImageCapture(camera)
                capture.capture(str(os.getcwd())+"//"+"999.jpg")

                # i also tried capture.capture("999.jpg") still no output 
                # (checked in Pictures folder)

            except Exception as e:
                print("Exception occured, ",e)
        else:
            print("Error")

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(251, 271)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.clickphotobtn = QtWidgets.QPushButton(self.centralwidget)
        self.clickphotobtn.setGeometry(QtCore.QRect(90, 110, 75, 23))
        self.clickphotobtn.setObjectName("clickphotobtn")

        # click event !!
        self.clickphotobtn.clicked.connect(self.clickphoto)

        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 251, 23))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.clickphotobtn.setText(_translate("MainWindow", "Capture"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

输出

PS C:\Users\Beast80K\Documents\Auto Brightness> & C:/Users/Beast80K/AppData/Local/Programs/Python/Python39/python.exe "c:/Users/Beast80K/Documents/Auto Brightness/trycappic.py"
clickphoto Called !
USB2.0 PC CAMERA
Unsupported media type: "{32595559-0000-0010-8000-00AA00389B71}"
Unsupported media type: "{32595559-0000-0010-8000-00AA00389B71}"
Unsupported media type: "{32595559-0000-0010-8000-00AA00389B71}"
Unsupported media type: "{32595559-0000-0010-8000-00AA00389B71}"
Unsupported media type: "{32595559-0000-0010-8000-00AA00389B71}"

你必须考虑到:

  1. 检查设备是否具有拍照功能。

  2. 照片的捕获是异步的,因此您必须使用信号来了解设备是否准备好拍照以及是否已完成保存照片。

import os
from pathlib import Path
from typing import ChainMap
import uuid

from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtMultimedia import QCamera, QCameraImageCapture, QCameraInfo

from gui import Ui_MainWindow

CURRENT_DIRECTORY = Path(__file__).resolve().parent
PHOTO_DIRECTORY = CURRENT_DIRECTORY / "photos"

PHOTO_DIRECTORY.mkdir(parents=True, exist_ok=True)


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.ui.clickphotobtn.clicked.connect(self.handle_clicked)

    def handle_clicked(self):
        self.capture()

    def capture(self):
        for camera_info in QCameraInfo.availableCameras():
            camera = QCamera(camera_info, self)
            if not camera.isCaptureModeSupported(QCamera.CaptureStillImage):
                print("Camera cannot capture images")
                continue
            camera.setCaptureMode(QCamera.CaptureStillImage)
            camer.errorOccurred.connect(self.handle_errorOccurred)
            camera.start()
            image_capture = QCameraImageCapture(camera, self)
            image_capture.readyForCaptureChanged.connect(
                self.handle_readyForCaptureChanged
            )
            image_capture.imageSaved.connect(self.handle_imageSaved)
            camera.searchAndLock()

    def handle_readyForCaptureChanged(self, ok):
        if ok:
            image_capture = self.sender()
            image_capture.capture(os.fspath(PHOTO_DIRECTORY / str(uuid.uuid4())))
            camera = image_capture.mediaObject()
            if isinstance(camera, QCamera):
                camera.unlock()

    def handle_imageSaved(self):
        image_capture = self.sender()
        camera = image_capture.mediaObject()
        if isinstance(camera, QCamera):
            camera.stop()
            camera.deleteLater()
        image_capture.deleteLater()

    def handle_errorOccurred(self, error):
        print(error, self.sender().errorString())

if __name__ == "__main__":
    import sys

    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

注意:不建议修改QtDesigner生成的代码,必须恢复文件调用gui.py