首页 > 解决方案 > 如何使用 PyQt5 QThread 从 CLASS(ShowVideo) 中获取值以在第二个 CLASS(ImageViewer) 中使用(根据我的程序)

问题描述

我正在尝试x从类中检索 ie的值,ShowVideo并在类中的按钮中显示该计数器ImageViewer。视频运行完美,但我没有了解如何在视频开始运行时显示计数器的逻辑。所有函数都应该同时工作,这里i的变量是startVideo()showVideo类下的函数内部声明的计数器名称。我想更新按钮上的值,即button_in(class ImageViewer, method InitUI())作为计数器。

'''

import cv2
import numpy as np
import sys
from PyQt5 import QtCore
from PyQt5 import QtWidgets
from PyQt5 import QtGui
from PyQt5.QtCore import pyqtSignal,QRect,QThread
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QPixmap

filenameOpen =0

class ShowVideo(QtCore.QObject):# its only running a videooo

    camera = cv2.VideoCapture(filenameOpen)

    VideoSignal = QtCore.pyqtSignal(QtGui.QImage)


#############################################
    # newValue=QtCore.pyqtSignal(int)
    # stopped= pyqtSignal()
#################################################    
    def __init__(self, parent = None):
        # super(ShowVideo, self).__init__(parent)
        super().__init__()

    @QtCore.pyqtSlot()
    def startVideo(self):

        run_video = True
        #     self.counterThread.startVideo()QImage
        x=0
        while run_video:
            # ret, image = self.camera.read()
            ret, image = self.camera.read()
            height, width, channels = image.shape
            frame=image.copy()
            frameClone = frame.copy()       
            # frame = cv2.resize(frame, (1920, 1080))

            color_swapped_image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            height, width, _ = color_swapped_image.shape


            qt_image = QtGui.QImage(color_swapped_image.data,
                                    width, 
                                    height,
                                    color_swapped_image.strides[0],
                                    QtGui.QImage.Format_RGB888)                    
            self.VideoSignal.emit(qt_image) 
            # return x
            # print(x)
            # x=x+1

class ImageViewer(QtWidgets.QMainWindow):
    def __init__(self, parent = None):
        super().__init__()
        left=0
        top=0
        width=1920
        height=1080
        iconName="icon.png"
        self.setWindowIcon(QtGui.QIcon(iconName))
        self.setGeometry(left,top,width,height)
        self.image = QtGui.QImage()
        self.initUI()
        self.show()

    def initUI(self):
        self.setWindowTitle('Emotion Analysis')
        button_video = QPushButton(self)
        button_file = QPushButton(self)
        button_play = QPushButton(self)
        self.button_in=QPushButton(self)
        button_out=QPushButton(self)
        button_total=QPushButton(self)
        self.button_stop = QPushButton(self)
        self.label_image=QLabel(self)
        label_image_blank=QLabel(self)
        label_in=QLabel(self)
        label_out=QLabel(self)
        label_total=QLabel(self)    

        # button definations>>>>>>>>>>>>>>>>>>>>
        button_video.setGeometry((QRect(10,30,90,65)))# syntax(x,y,<>,^)
        button_video.setIcon(QtGui.QIcon("securitycamera.png"))
        button_video.setIconSize(QtCore.QSize(50,50))
        # button.setToolTip("This is Click Me Button")
        button_video.setToolTip("<h4>Live Stream<h4>")
        button_video.clicked.connect(vid.startVideo)

        button_file.setGeometry((QRect(110,30,90,65)))# syntax(x,y,<>,^)
        button_file.setIcon(QtGui.QIcon("file.png"))
        button_file.setIconSize(QtCore.QSize(50,50))
        button_file.setToolTip("<h4>Add new connection<h4>")
        button_file.clicked.connect(QtWidgets.qApp.quit) # this line is also working condition, the quit() method is defined above 

        button_play.setGeometry((QRect(1710,30,90,65)))# syntax(x,y,<>,^)
        # button_play.setGeometry((QRect(1710,300,90,65)))# syntax(x,y,<>,^)
        button_play.setIcon(QtGui.QIcon("play_red.png"))
        button_play.setIconSize(QtCore.QSize(50,50))
        button_play.setToolTip("<h4>Play video<h4>")
        button_play.clicked.connect(vid.startVideo)

        self.button_stop.setGeometry((QRect(1820,30,90,65)))# syntax(x,y,<>,^)
        self.button_stop.setIcon(QtGui.QIcon("stop.png"))
        self.button_stop.setIconSize(QtCore.QSize(50,50))
        self.button_stop.setToolTip("<h4>Stop Video<h4>")
        self.button_stop.clicked.connect(QApplication.instance().quit)
#############################################################
        self.button_in.setGeometry((QRect(1710,500,90,45)))# syntax(x,y,<>,^)
        self.button_in.setText("0")# it should be updated while counter runs
        # self.button_in.setText(x)
        self.button_in.setFont(QtGui.QFont("Sanserif",20))

        # self.counterThread=QThread()
        # self.counter=ShowVideo()
        # self.counter.moveToThread(self.counterThread)
        # self.button_in.clicked.connect(self.startCounting)
        # self.vid.newValue.connect(self.button_in.setText)
        # self.counterThread.started.connect(self.counter.startVideo)





#####################################################################
        button_out.setGeometry((QRect(1710,550,90,45)))# syntax(x,y,<>,^)
        button_out.setText("0")
        button_out.setFont(QtGui.QFont("Sanserif",20))

        button_total.setGeometry((QRect(1710,600,90,45)))# syntax(x,y,<>,^)
        button_total.setText("0")
        button_total.setFont(QtGui.QFont("Sanserif",20))


        # label definations>>>>>>>>>>>>>>>>>>>>

        self.label_image.setGeometry((QRect(10,110,1500,900))) # syntax(x,y,<>,^)
        self.label_image.setPixmap(QPixmap("black.jpg"))
        self.label_image.setScaledContents(True)

        label_in.setGeometry((QRect(1600,500,100,50))) # syntax(x,y,<>,^)
        label_in.setText("In")
        label_in.setFont(QtGui.QFont("Sanserif",20))

        label_out.setGeometry((QRect(1600,550,100,50))) # syntax(x,y,<>,^)
        label_out.setText("Out")
        label_out.setFont(QtGui.QFont("Sanserif",20))

        label_total.setGeometry((QRect(1600,600,100,50))) # syntax(x,y,<>,^)
        label_total.setText("Total")
        label_total.setFont(QtGui.QFont("Sanserif",20))     

    @QtCore.pyqtSlot(QtGui.QImage)
    def setImage(self, image):
        self.label_image.setPixmap(QPixmap.fromImage(image))
        # self.vid.newValue.connect(self.button_in.setText)



    # @QtCore.pyqtSlot(int)
    # def startCounting(self,x):
    # #     # if not self.counterThread.isRunning():
    # #     #     self.counterThread.startVideo()
    # #     # pass
    #     self.vid.newValue.connect(self.button_in.setText)

if __name__ == '__main__':

    app = QtWidgets.QApplication(sys.argv)
    thread = QtCore.QThread() #thread declareation
    thread.start()
    vid = ShowVideo() # calling 1st class
    vid.moveToThread(thread)
    image_viewer = ImageViewer() #calling second class 
    vid.VideoSignal.connect(image_viewer.setImage)  
    # vid.VideoSignal.connect(image_viewer.startCounting)   
    sys.exit(app.exec_()) '''

标签: pythonpyqt5qthread

解决方案


ShowVideo.VideoSignal可能最简单的方法是在发射ShowVideo.startVedio和连接vid.VideoSignal到时发射带有图像的帧号image_viewer.setText,即

class ShowVideo(QtCore.QObject):

    VideoSignal = QtCore.pyqtSignal(QtGui.QImage, int)

    ....

    @QtCore.pyqtSlot()
    def startVideo(self):

        ....

        x += 1
        self.VideoSignal.emit(qt_image, x)

....

if __name__ == '__main__':

    ....

    vid.VideoSignal.connect(lambda img, frame: image_viewer.button_in.setText(str(frame)) )

推荐阅读