我目前正在为我使用 OpenCV 制作的监控系统编写 GUI。我想在设置框旁边的 QLabel 中查看实时视频输入,但我对发射/信号/插槽主题很陌生,所以我对代码顺序有点不知所措。 GUI 是从 QtCreator 转换过来的,只是为了让 Layout 正确。这些按钮还没有任何功能。 到目前为止,这是我的代码:
import sys
import cv2
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
#getting the live vid
class Thread(QThread):
changePixmap = pyqtSignal(QImage)
def run(self):
cap1 = cv2.VideoCapture('single.mp4')
while True:
ret, frame = cap1.read()
rgb_image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
cvt2qt = QImage(rgb_image.data, rgb_image.shape[1], rgb_image.shape[0], QImage.Format_RGB888)
self.changePixmap.emit(cvt2qt) # I don't really understand this yet
class Ui_MainWindow(object):
def setImage(self, image):
self.label.setPixmap(QPixmap.fromImage(image))
@pyqtSlot(QImage) # I'm not sure about this function
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1280, 779)
MainWindow.setMinimumSize(QtCore.QSize(920, 405))
self.centralWidget = QtWidgets.QWidget(MainWindow)
self.centralWidget.setMinimumSize(QtCore.QSize(400, 400))
self.centralWidget.setBaseSize(QtCore.QSize(800, 600))
self.centralWidget.setObjectName("centralWidget")
# here is where I want to put the image.
self.label = QtWidgets.QLabel(self.centralWidget)
self.label.setGeometry(QtCore.QRect(10, 10, 881, 671))
self.label.setScaledContents(True)
self.label.setObjectName("label")
th = Thread(self) # Here is, where I struggle
th.changePixmap.connect(self.setImage)
th.start()
MainWindow.setCentralWidget(self.centralWidget)
self.dockWidget = QtWidgets.QDockWidget(MainWindow)
self.dockWidget.setMinimumSize(QtCore.QSize(200, 0))
self.dockWidget.setLayoutDirection(QtCore.Qt.LeftToRight)
self.dockWidget.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable)
self.dockWidget.setAllowedAreas(QtCore.Qt.LeftDockWidgetArea|QtCore.Qt.RightDockWidgetArea)
self.dockWidget.setObjectName("dockWidget")
self.dockWidgetContents = QtWidgets.QWidget()
self.dockWidgetContents.setObjectName("dockWidgetContents")
self.groupBox = QtWidgets.QGroupBox(self.dockWidgetContents)
self.groupBox.setGeometry(QtCore.QRect(0, 30, 141, 281))
self.groupBox.setMinimumSize(QtCore.QSize(90, 0))
self.groupBox.setObjectName("groupBox")
self.pushButton = QtWidgets.QPushButton(self.groupBox)
self.pushButton.setGeometry(QtCore.QRect(10, 20, 121, 32))
self.pushButton.setObjectName("pushButton")
self.pushButton_2 = QtWidgets.QPushButton(self.groupBox)
self.pushButton_2.setGeometry(QtCore.QRect(10, 50, 121, 32))
self.pushButton_2.setObjectName("pushButton_2")
self.pushButton_3 = QtWidgets.QPushButton(self.groupBox)
self.pushButton_3.setGeometry(QtCore.QRect(10, 80, 121, 32))
self.pushButton_3.setObjectName("pushButton_3")
self.radioButton = QtWidgets.QRadioButton(self.groupBox)
self.radioButton.setGeometry(QtCore.QRect(20, 120, 100, 20))
self.radioButton.setObjectName("radioButton")
self.radioButton_2 = QtWidgets.QRadioButton(self.groupBox)
self.radioButton_2.setGeometry(QtCore.QRect(20, 150, 100, 20))
self.radioButton_2.setObjectName("radioButton_2")
self.radioButton_3 = QtWidgets.QRadioButton(self.groupBox)
self.radioButton_3.setGeometry(QtCore.QRect(20, 180, 100, 20))
self.radioButton_3.setObjectName("radioButton_3")
self.dockWidget.setWidget(self.dockWidgetContents)
MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(2), self.dockWidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "ARCV"))
self.groupBox.setTitle(_translate("MainWindow", "Settings"))
self.pushButton.setText(_translate("MainWindow", "Start Recording"))
self.pushButton_2.setText(_translate("MainWindow", "Stop Recording"))
self.pushButton_3.setText(_translate("MainWindow", "Quit GUI"))
self.radioButton.setText(_translate("MainWindow", "Camera 1"))
self.radioButton_2.setText(_translate("MainWindow", "Camera 2"))
self.radioButton_3.setText(_translate("MainWindow", "Camera 3"))
class Prog(QMainWindow):
def __init__(self):
super().__init__();
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
if __name__=='__main__':
Program = QApplication(sys.argv)
MyProg = Prog()
MyProg.show()
sys.exit(Program.exec_())
我希望,你能帮助我。谢谢。 骑士
最佳答案
QThread
等待作为必须是 QObject
的父级的参数,在您的情况下,self 是 Ui_MainWindow
类的对象不继承自导致问题的QObject
。
我看到您正在实现一个名为 Prog 的类,您必须在其中执行逻辑而不是修改 Qt Designer 生成的代码。
因此,如果我们将逻辑移至该类,应该没有问题。
另一方面,装饰器@pyqtSlot
必须在连接到信号的函数中使用,你把它放在没有意义的构造函数中,它必须在 setImage()
.
import sys
import cv2
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1280, 779)
MainWindow.setMinimumSize(QtCore.QSize(920, 405))
self.centralWidget = QtWidgets.QWidget(MainWindow)
self.centralWidget.setMinimumSize(QtCore.QSize(400, 400))
self.centralWidget.setBaseSize(QtCore.QSize(800, 600))
self.centralWidget.setObjectName("centralWidget")
# here is where I want to put the image.
self.label = QtWidgets.QLabel(self.centralWidget)
self.label.setGeometry(QtCore.QRect(10, 10, 881, 671))
self.label.setScaledContents(True)
self.label.setObjectName("label")
MainWindow.setCentralWidget(self.centralWidget)
self.dockWidget = QtWidgets.QDockWidget(MainWindow)
self.dockWidget.setMinimumSize(QtCore.QSize(200, 0))
self.dockWidget.setLayoutDirection(QtCore.Qt.LeftToRight)
self.dockWidget.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable)
self.dockWidget.setAllowedAreas(QtCore.Qt.LeftDockWidgetArea|QtCore.Qt.RightDockWidgetArea)
self.dockWidget.setObjectName("dockWidget")
self.dockWidgetContents = QtWidgets.QWidget()
self.dockWidgetContents.setObjectName("dockWidgetContents")
self.groupBox = QtWidgets.QGroupBox(self.dockWidgetContents)
self.groupBox.setGeometry(QtCore.QRect(0, 30, 141, 281))
self.groupBox.setMinimumSize(QtCore.QSize(90, 0))
self.groupBox.setObjectName("groupBox")
self.pushButton = QtWidgets.QPushButton(self.groupBox)
self.pushButton.setGeometry(QtCore.QRect(10, 20, 121, 32))
self.pushButton.setObjectName("pushButton")
self.pushButton_2 = QtWidgets.QPushButton(self.groupBox)
self.pushButton_2.setGeometry(QtCore.QRect(10, 50, 121, 32))
self.pushButton_2.setObjectName("pushButton_2")
self.pushButton_3 = QtWidgets.QPushButton(self.groupBox)
self.pushButton_3.setGeometry(QtCore.QRect(10, 80, 121, 32))
self.pushButton_3.setObjectName("pushButton_3")
self.radioButton = QtWidgets.QRadioButton(self.groupBox)
self.radioButton.setGeometry(QtCore.QRect(20, 120, 100, 20))
self.radioButton.setObjectName("radioButton")
self.radioButton_2 = QtWidgets.QRadioButton(self.groupBox)
self.radioButton_2.setGeometry(QtCore.QRect(20, 150, 100, 20))
self.radioButton_2.setObjectName("radioButton_2")
self.radioButton_3 = QtWidgets.QRadioButton(self.groupBox)
self.radioButton_3.setGeometry(QtCore.QRect(20, 180, 100, 20))
self.radioButton_3.setObjectName("radioButton_3")
self.dockWidget.setWidget(self.dockWidgetContents)
MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(2), self.dockWidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "ARCV"))
self.groupBox.setTitle(_translate("MainWindow", "Settings"))
self.pushButton.setText(_translate("MainWindow", "Start Recording"))
self.pushButton_2.setText(_translate("MainWindow", "Stop Recording"))
self.pushButton_3.setText(_translate("MainWindow", "Quit GUI"))
self.radioButton.setText(_translate("MainWindow", "Camera 1"))
self.radioButton_2.setText(_translate("MainWindow", "Camera 2"))
self.radioButton_3.setText(_translate("MainWindow", "Camera 3"))
#getting the live vid
class Thread(QtCore.QThread):
changePixmap = QtCore.pyqtSignal(QtGui.QImage)
def __init__(self, *args, **kwargs):
QtCore.QThread.__init__(self, *args, **kwargs)
self.flag = False
def run(self):
cap1 = cv2.VideoCapture('single.mp4')
self.flag = True
while self.flag:
ret, frame = cap1.read()
if ret:
rgb_image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
cvt2qt = QtGui.QImage(rgb_image.data, rgb_image.shape[1], rgb_image.shape[0], QtGui.QImage.Format_RGB888)
self.changePixmap.emit(cvt2qt) # I don't really understand this yet
def stop(self):
self.flag = False
class Prog(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.th = Thread(self)
self.th.changePixmap.connect(self.setImage)
self.th.start()
@QtCore.pyqtSlot(QtGui.QImage)
def setImage(self, image):
self.label.setPixmap(QtGui.QPixmap.fromImage(image))
def closeEvent(self, event):
self.th.stop()
self.th.wait()
super().closeEvent(event)
if __name__=='__main__':
Program = QtWidgets.QApplication(sys.argv)
MyProg = Prog()
MyProg.show()
sys.exit(Program.exec_())
关于python - 在 QLabel 元素中实时显示 CV2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50880850/