如何使用 PyQt5 QThread 从 CLASS(ShowVideo) 中获取值以在第二个 CLASS(ImageViewer) 中使用(根据我的程序)
Posted
技术标签:
【中文标题】如何使用 PyQt5 QThread 从 CLASS(ShowVideo) 中获取值以在第二个 CLASS(ImageViewer) 中使用(根据我的程序)【英文标题】:How to fetch value from a CLASS(ShowVideo) to use in second CLASS(ImageViewer) (according to my program) by using PyQt5 QThread 【发布时间】:2019-11-20 08:28:23 【问题描述】:我正在尝试检索 x
的值,即是来自 ShowVideo
类的计数器,并在 ImageViewer
类的按钮中显示计数器。视频运行完美,但我没有了解如何在视频开始运行时显示计数器的逻辑。所有函数应该同时工作,这里i
作为变量是在showVideo
类下的函数startVideo()
中声明的计数器名称。我想更新按钮上的值,即 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_()) '''
【问题讨论】:
不要为了吸引注意力而用噪音编辑您的问题。 【参考方案1】:可能最简单的方法是在ShowVideo.startVedio
中发射ShowVideo.VideoSignal
并将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)) )
【讨论】:
与计数器配合良好,但相机已开启但无法运行视频以上是关于如何使用 PyQt5 QThread 从 CLASS(ShowVideo) 中获取值以在第二个 CLASS(ImageViewer) 中使用(根据我的程序)的主要内容,如果未能解决你的问题,请参考以下文章
PyQt5 - 如何在使用 QThread 时减少 CPU 使用率(低于 50%)?