本文中所使用的为PySide6,但是对于PySide2同样适用
from PySide6.QtWidgets import QMessageBox
from PySide6.QtGui import *
from PySide6.QtWidgets import *
from PySide6.QtCore import *
from PySideUI import Ui_MainWindow # 从由ui文件转换而来的Py文件中导入主要函数
import cv2
class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.cap = cv2.VideoCapture()
self.button_set()
'''
图像显示主要用到了QTimer这个Qt中的计时器组件:
instance = QTimer(widget) # 初始化生成计时器实例
instance.start(timeout) # 每 timeout 时间后在父组件的基础上发出一个计时信号
instance.timeout.connect(self.show_picture) # 我们可以设计一个槽函数用于不断接收这个计时信号,从而实现图像帧的不断显示
instance.stop # 关闭计时器
'''
self.timer = QTimer(self)
self.timer.timeout.connect(self.show_picture)
'''
槽函数,该槽函数用于接收及处理 “打开摄像头” 按钮发来的按钮信号
'''
def open_camera(self):
number = self.comboBox.currentIndex() # 获取当前复选框的索引值,其是依次排列的0、1、2、...
flag = self.cap.open(number) # 打开指定的摄像头,若成功打开,该函数会返回 Ture、否之则返回False
if flag is False:
QMessageBox.information(self, "警告", "该设备未正常工作", QMessageBox.Ok)
else:
self.label.setEnabled(True) # 此句可删
self.pushButton.setEnabled(False)
self.pushButton_2.setEnabled(True)
self.timer.start() # Qt计时器开始运行,不断的发出计时信号,不断的跳入到show_pic槽函数中,不断的显示图像
'''
槽函数,该槽函数用于接收及处理 “关闭摄像头” 按钮发来的按钮信号
'''
def close_camera(self):
self.cap.release() # 释放摄像头对象
self.pushButton.setEnabled(True)
self.pushButton_2.setEnabled(False)
self.timer.stop() # 停止计时器,不再显示图像帧
self.label.setText(" ") # 清空Label,使之重回黑屏状态
def button_set(self):
self.pushButton.clicked.connect(self.open_camera)
self.pushButton_2.clicked.connect(self.close_camera)
self.pushButton.setEnabled(True)
self.pushButton_2.setEnabled(False)
def show_picture(self):
ret, frame = self.cap.read()
if ret:
if frame is not None:
cur_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
height, width = cur_frame.shape[:2] # cur_frame=会返回图像的高、宽与颜色通道数,截前2
'''
QImage用于访问、转化图像格式操作图像等,其返回值是一个已经转化好格式的QImage对象。
QImage支持格式枚举描述的几种图像格式,包括单色、8位、32位和alpha混合图像。当然也包括Opencv的 mat 类型数组枚举形式
格式: QImage(枚举对象图像帧,宽,高,转化成的颜色格式)
'''
pixmap = QImage(cur_frame, width, height, QImage.Format_RGB888)
'''
QPixmap用于在屏幕上显示图像, 其返回值是一个QPixmap对象
QPixmap.fromImage函数用于将QImage对象转化为QPixmap对象,注意QPixmap并非一个图像帧,而是Qt中用于图像展示的一个类对象实例
其本身也是一种抽象的封装,可被Qt中其他的类对象进行图像显示操作。
'''
pixmap = QPixmap.fromImage(pixmap)
# 获取是视频流和 label 窗口的长宽比值的最大值,适应label窗口播放,不然显示不全
ratio = max(width/self.label.width(), height/self.height())
pixmap.setDevicePixelRatio(ratio) # 以适应比例将图像帧置入 Label 中进行播放
# 视频流置于label中间部分播放
self.label.setAlignment(Qt.AlignCenter)
self.label.setPixmap(pixmap)
if __name__ == '__main__':
app = QApplication([])
main = MainWindow()
main.show()
app.exec()
另附PySideUI.py文件内容:
# -*- coding: utf-8 -*-
################################################################################
## Form generated from reading UI file 'PySide_UI.ui'
##
## Created by: Qt User Interface Compiler version 6.5.0
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
QMetaObject, QObject, QPoint, QRect,
QSize, QTime, QUrl, Qt)
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
QFont, QFontDatabase, QGradient, QIcon,
QImage, QKeySequence, QLinearGradient, QPainter,
QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QApplication, QComboBox, QLabel, QMainWindow,
QMenuBar, QPushButton, QSizePolicy, QStatusBar,
QWidget)
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
if not MainWindow.objectName():
MainWindow.setObjectName(u"MainWindow")
MainWindow.resize(850, 663)
self.centralwidget = QWidget(MainWindow)
self.centralwidget.setObjectName(u"centralwidget")
self.label = QLabel(self.centralwidget)
self.label.setObjectName(u"label")
self.label.setGeometry(QRect(0, 0, 851, 471))
self.label.setStyleSheet(u"background-color: rgb(0, 0, 0);")
self.pushButton = QPushButton(self.centralwidget)
self.pushButton.setObjectName(u"pushButton")
self.pushButton.setGeometry(QRect(10, 490, 291, 131))
self.pushButton_2 = QPushButton(self.centralwidget)
self.pushButton_2.setObjectName(u"pushButton_2")
self.pushButton_2.setGeometry(QRect(550, 490, 291, 131))
self.comboBox = QComboBox(self.centralwidget)
self.comboBox.addItem("")
self.comboBox.addItem("")
self.comboBox.setObjectName(u"comboBox")
self.comboBox.setGeometry(QRect(350, 490, 151, 51))
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QMenuBar(MainWindow)
self.menubar.setObjectName(u"menubar")
self.menubar.setGeometry(QRect(0, 0, 850, 22))
MainWindow.setMenuBar(self.menubar)
self.statusbar = QStatusBar(MainWindow)
self.statusbar.setObjectName(u"statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QMetaObject.connectSlotsByName(MainWindow)
# setupUi
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
self.label.setText("")
self.pushButton.setText(QCoreApplication.translate("MainWindow", u"\u6253\u5f00\u6444\u50cf\u5934", None))
self.pushButton_2.setText(QCoreApplication.translate("MainWindow", u"\u5173\u95ed\u6444\u50cf\u5934", None))
self.comboBox.setItemText(0, QCoreApplication.translate("MainWindow", u"\u7b14\u8bb0\u672c\u6444\u50cf\u5934", None))
self.comboBox.setItemText(1, QCoreApplication.translate("MainWindow", u"\u5916\u7f6e\u6444\u50cf\u5934", None))
# retranslateUi