我正在为使用OpenCV制作的监控系统编写GUI。我想在设置框旁边的QLabel中看到实时视频输入,但我对emit / signal / slot主题很新,所以我对代码顺序有点不知所措。 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_())
我希望,你可以帮助我。谢谢。 Aaroknight
答案 0 :(得分:0)
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_())