gpt4 book ai didi

python - 使用QThread的PyQt5 OpenCV WebCam

转载 作者:行者123 更新时间:2023-12-02 16:24:31 25 4
gpt4 key购买 nike

我使用PyQt5和OpenCV编写了一个网络摄像头应用程序。它工作正常,但是我想对其进行更多改进。我有几个问题:

1)在WebCam.py的第24行,当我单击退出按钮时,我想正确地打破while循环。我的意思是我需要以某种方式从“Ui_MainWindow”类定义“运行” bool(boolean) 值并将其传递给FrameGrabber类,以中断while循环,例如while cap.isOpened() & running:循环中断后,我可以正确释放视频捕获。

2)Ui_MainWindow主要由Qt设计器生成。我必须在其中添加代码以利用面向对象的封装规则,例如不定义全局变量。但是,如果需要在UI中进行更改,是否需要一直编写代码?更新UI后,不更改代码的正确方法是什么?

3)如果您认为该代码对于代码的任何部分都更好,请随时发表评论,以便我也可以提高自己的技能。

先感谢您!

这是WebCam.py:

from PyQt5 import QtCore, QtGui, QtWidgets
import cv2


class FrameGrabber(QtCore.QThread):
def __init__(self, parent=None):
super(FrameGrabber, self).__init__(parent)

signal = QtCore.pyqtSignal(QtGui.QImage)

def run(self):
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
while cap.isOpened():
success, frame = cap.read()
if success:
image = QtGui.QImage(frame, frame.shape[1], frame.shape[0], QtGui.QImage.Format_BGR888)
self.signal.emit(image)

class Ui_MainWindow(QtWidgets.QMainWindow):
def __init__(self, MainWindow):
super().__init__()
self.MainWindow = MainWindow
self.setupUi(self.MainWindow)
self.grabber = FrameGrabber()
self.grabber.signal.connect(self.updateFrame)
self.grabber.start()

def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.setWindowModality(QtCore.Qt.NonModal)
MainWindow.resize(1300, 799)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth())
MainWindow.setSizePolicy(sizePolicy)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setObjectName("verticalLayout")
self.label = QtWidgets.QLabel(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth())
self.label.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(12)
font.setBold(True)
font.setUnderline(True)
font.setWeight(75)
self.label.setFont(font)
self.label.setFrameShape(QtWidgets.QFrame.Box)
self.label.setTextFormat(QtCore.Qt.RichText)
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setObjectName("label")
self.verticalLayout.addWidget(self.label)
self.webCamDisplay = QtWidgets.QLabel(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.webCamDisplay.sizePolicy().hasHeightForWidth())
self.webCamDisplay.setSizePolicy(sizePolicy)
self.webCamDisplay.setFrameShape(QtWidgets.QFrame.Box)
self.webCamDisplay.setText("")
self.webCamDisplay.setObjectName("webCamDisplay")
self.verticalLayout.addWidget(self.webCamDisplay)
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
spacerItem = QtWidgets.QSpacerItem(500, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem)
self.quitPushButton = QtWidgets.QPushButton(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.quitPushButton.sizePolicy().hasHeightForWidth())
self.quitPushButton.setSizePolicy(sizePolicy)
self.quitPushButton.setObjectName("quitPushButton")
self.horizontalLayout.addWidget(self.quitPushButton)
self.verticalLayout.addLayout(self.horizontalLayout)
self.verticalLayout_2.addLayout(self.verticalLayout)
MainWindow.setCentralWidget(self.centralwidget)
MainWindow.setFixedSize(MainWindow.width(), MainWindow.height())
self.quitPushButton.clicked.connect(self.quitApp)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)

@QtCore.pyqtSlot(QtGui.QImage)
def updateFrame(self, image):
self.webCamDisplay.setPixmap(QtGui.QPixmap.fromImage(image))

def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "WebCam"))
self.label.setText(_translate("MainWindow", "WebCam Application"))
self.quitPushButton.setText(_translate("MainWindow", "Quit"))

def quitApp(self):
QtWidgets.QApplication.quit()

main.py:
from WebCam import Ui_MainWindow
from PyQt5.QtWidgets import QApplication, QMainWindow

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

最佳答案

这是您应该知道的:

  • 中Qt UI线程只能通过功能来控制和更新
    或再次连接到同一线程的任何东西。
  • 如果您没有创建任何线程,那么代码中的所有内容都将连接到ui线程。
  • 特别是在使用相机并对其进行一些处理时,界面中可能会出现抖动问题,因为 ui线程正在等待自身更新,直到该过程在后台完成。我认为您还使用另一个线程来解决此问题。
  • 因为它不是ui线程,所以不可能在新线程上为ui发出东西给ui。为了从另一个线程发出东西,您可以使用全局值。您可以在线程中更改全局值,也可以在连接到 ui线程的另一个函数中进行更新。在这种情况下,应使用互斥锁
  • 当您检查有关 QThread 类的documentation时,控制线程及其正常功能的功能有限。基本上,您可以停止线程或启动线程,没有暂停。当您想关闭在线程中的while循环中运行的摄像头时,您可以关闭线程内部,但线程ll仍在运行,或者您可以关闭线程。
  • 结果,如果使用必要的线程进行一些视频处理。对于简单的过程,不需要。
  • 关于python - 使用QThread的PyQt5 OpenCV WebCam,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62315869/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com