Reputation: 45
I wrote a webcam app using PyQt5 and OpenCV. It works fine, however I would like to improve it more. I have couple of questions:
1) At line 24 of WebCam.py, I would like to break the while loop properly, when I click the quit push button. I mean I need to define and pass a "running" boolean value somehow from "Ui_MainWindow" class to FrameGrabber class to break the while loop, such as while cap.isOpened() & running:
Once the loop is broken, I can properly release the video capture.
2) Ui_MainWindow is mostly generated by the Qt Designer. I had to add code inside it to utilize Object Oriented Encapsulation rules, such as not defining a global variable. However, if I needed to make a change in the UI, do I need to write code all the time? What is the proper way of not changing the code, once the UI is updated?
3) Please feel free to make comments if you think that the code would be better for any section of it, so that I can also improve my skills.
Thank you in advance!
Here is 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_())
Upvotes: 3
Views: 2799
Reputation: 4367
Here are something you should know:
Upvotes: 2