繁体   English   中英

PyQt5多线程

[英]PyQt5 multi thread

为什么代码不起作用? 视频工作文件,当我试图在第二个标签显示文本时,它也显示出来。但如果我想像setText()中的当前时间那样连续更改值,我该怎么办? 我是多线程新手。

import sys
import cv2
from PyQt5.QtCore import QThread, pyqtSignal, Qt
from PyQt5.QtGui import QPixmap, QImage
from PyQt5.QtWidgets import QApplication, QWidget, QLabel
import datetime


class App(QWidget):
    def __init__(self):
        super().__init__()
        self.title = 'PyQt5 Video'
        self.left = 100
        self.top = 100
        self.width = 640
        self.height = 480
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        self.resize(1800, 1200)
        # create a label
        label = QLabel(self)
        label.move(280, 120)
        label.resize(640, 480)
        label1 = QLabel(self)
        label1.move(680, 820)
        th = Thread(self)
        th.changePixmap.connect(lambda p: label.setPixmap(p))
        th.changeLabel.connect(lambda n:label1.setText("A"))
        th.start()

class Thread(QThread):
    changePixmap = pyqtSignal(QPixmap)
    changeLabel = pyqtSignal(QLabel)

    def __init__(self, parent=None):
        QThread.__init__(self, parent=parent)

    def run(self):
        cap = cv2.VideoCapture(0)
        n=QLabel()
        while True:
            ret, frame = cap.read()
            rgbImage = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            convertToQtFormat = QImage(rgbImage.data, rgbImage.shape[1], rgbImage.shape[0], QImage.Format_RGB888)
            convertToQtFormat = QPixmap.fromImage(convertToQtFormat)
            p = convertToQtFormat.scaled(640, 480, Qt.KeepAspectRatio)
            self.changePixmap.emit(p)
            now = datetime.datetime.now()
            sec = now.second
            try:
                self.changeLabel.emit(n)
            except Exception as e:
                print(str(e))

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    ex.show()
    sys.exit(app.exec_())

您不应该将新窗口小部件(QLabel)发送到主视图,因为它将是新标签,而不是原始标签,您应该发送str类型的文本。

class Thread(QThread):
    changePixmap = pyqtSignal(QPixmap)
    changeLabel = pyqtSignal(str)

    def run(self):
        [...]
        now = datetime.datetime.now()
        sec = now.second
        self.changeLabel.emit(str(sec))

然后将其连接到setText函数:

th.changeLabel.connect(label1.setText)

完整代码:

import sys
import cv2
from PyQt5.QtCore import QThread, pyqtSignal, Qt
from PyQt5.QtGui import QPixmap, QImage
from PyQt5.QtWidgets import QApplication, QWidget, QLabel
import datetime


class App(QWidget):
    def __init__(self):
        super().__init__()
        self.title = 'PyQt5 Video'
        self.left = 100
        self.top = 100
        self.width = 640
        self.height = 480
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        self.resize(1800, 1200)
        # create a label
        # create a label
        label = QLabel(self)
        label.move(280, 120)
        label.resize(640, 480)
        label1 = QLabel(self)
        label1.move(580, 620)
        self.th = Thread(self)
        self.th.changePixmap.connect(label.setPixmap)
        self.th.changeLabel.connect(label1.setText)
        self.th.start()

    def closeEvent(self, event):
        self.th.stop()
        QWidget.closeEvent(self, event)

class Thread(QThread):
    changePixmap = pyqtSignal(QPixmap)
    changeLabel = pyqtSignal(str)

    def __init__(self, parent=None):
        QThread.__init__(self, parent=parent)
        self.isRunning = True

    def run(self):
        cap = cv2.VideoCapture(0)
        while self.isRunning:
            ret, frame = cap.read()
            rgbImage = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            convertToQtFormat = QImage(rgbImage.data, rgbImage.shape[1], rgbImage.shape[0], QImage.Format_RGB888)
            convertToQtFormat = QPixmap.fromImage(convertToQtFormat)
            p = convertToQtFormat.scaled(640, 480, Qt.KeepAspectRatio)
            self.changePixmap.emit(p)
            now = datetime.datetime.now()
            sec = now.second
            self.changeLabel.emit(str(sec))

    def stop(self):
        self.isRunning = False
        self.quit()
        self.wait()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    ex.show()
    sys.exit(app.exec_())

注意:我添加了stop方法以便能够停止线程并正确关闭,为此我也覆盖了closeEvent方法。 另一个变化,我移动label1,因为我的屏幕不是那么大。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM