代码之家  ›  专栏  ›  技术社区  ›  batuman

PyQT5中的信号和插槽

  •  1
  • batuman  · 技术社区  · 7 年前

    我在Python2.7中使用PyQt5。我有三节课。 Thread, PlayStreaming and UIWidget

    class Thread(QtCore.QThread):
        changePixmap = QtCore.pyqtSignal(QtGui.QImage)
        scaled_size = QtCore.QSize(640, 480)
        curScale=1.0
        maxHeight=0
        maxScale=0
        def run(self):
            cap = cv2.VideoCapture(1)
            cap.set(3,1280);
            cap.set(4,1024);
            time.sleep(2)
            maxHeight=cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
            maxScale=maxHeight/480.0
            while True:
                ret, frame = cap.read()                  
                if ret:
                    r=1
                    face_locations=[]
                    rescaleSize=int(480*curScale)
                    if(frame.shape[0] > 480 and frame.shape[1] > 640):
                        r = rescaleSize / float(frame.shape[0])
                        dim = (int(frame.shape[1] * r), rescaleSize)
                        face_locations = face_recognition.face_locations(cv2.resize(frame, dim, fx=0.0, fy=0.0))
                    else:
                        face_locations = face_recognition.face_locations(frame)
                    for face_location in face_locations:  
                        top, right, bottom, left = face_location
                        cv2.rectangle(frame,(int(right/r),int(top/r)),(int(left/r),int(bottom/r)),(0,255,0),2)
                    rgbImage = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                    convertToQtFormat = QtGui.QImage(rgbImage.data, rgbImage.shape[1], rgbImage.shape[0], QtGui.QImage.Format_RGB888)
                    p = convertToQtFormat.scaled(self.scaled_size, QtCore.Qt.KeepAspectRatio)
                    self.changePixmap.emit(p)
    
        def scaled(self, scaled_size):
            self.scaled_size = scaled_size 
    
        def scaleup(self):
            self.curScale = self.curScale + 0.1
            if( self.curScale > maxScale):
                self.curScale=maxScale
            print(self.curScale)
    
    
    class PlayStreaming(QtWidgets.QLabel):
        reSize = QtCore.pyqtSignal(QtCore.QSize)
        def __init__(self):
            super(PlayStreaming, self).__init__()
            self.initUI()
    
        @QtCore.pyqtSlot(QtGui.QImage)
        def setImage(self, image):
            self.label.setPixmap(QtGui.QPixmap.fromImage(image))
    
        def initUI(self):
            self.setWindowTitle("Image")
            # create a label
            self.label = QtWidgets.QLabel(self)
            ##############instance of Thread############
            th = Thread(self)
            ############################################
            th.changePixmap.connect(self.setImage)
            self.reSize.connect(th.scaled)
            th.start()
            lay = QtWidgets.QVBoxLayout(self)
            lay.addWidget(self.label, alignment=QtCore.Qt.AlignCenter)
    
        def resizeEvent(self, event):
            self.reSize.emit(self.size())
    
    
    class UIWidget(QtWidgets.QWidget):
    
        def __init__(self, parent=None):
            super(UIWidget, self).__init__(parent)
            # Initialize tab screen
            self.tabs = QtWidgets.QTabWidget()
            self.tab1 = QtWidgets.QWidget()
            self.tab2 = QtWidgets.QWidget()
            self.tab3 = QtWidgets.QWidget()
    
            # Add tabs
            self.tabs.addTab(self.tab1, "Face")
            self.tabs.addTab(self.tab2, "Human")
            self.tabs.addTab(self.tab3, "Vehicle")
    
            # Create first tab
            self.createGridLayout()
            self.tab1.layout = QtWidgets.QVBoxLayout()
            ##############instance of PlayStreaming############
            self.display = PlayStreaming()
            ###################################################
            self.tab1.layout.addWidget(self.display, stretch=1)
            self.tab1.layout.addWidget(self.horizontalGroupBox)
            self.tab1.setLayout(self.tab1.layout)
    
            # Add tabs to widget
            layout = QtWidgets.QVBoxLayout(self)
            layout.addWidget(self.tabs)
    
        def createGridLayout(self):
            self.horizontalGroupBox = QtWidgets.QGroupBox("")
        self.horizontalGroupBox.setStyleSheet("QGroupBox{ background-color: red; border: none;}")  
        hlay1 = QtWidgets.QHBoxLayout()
        self.TestButton=QtWidgets.QPushButton('Test')
        hlay1.addWidget(self.TestButton) 
        self.RunButton=QtWidgets.QPushButton('Run')
        hlay1.addWidget(self.RunButton) 
        self.ScaleUpButton=QtWidgets.QPushButton('ScaleUp')
        ###################This button clicked signal to Thread class#########
        #############How to send??????????????????????########################
        self.ScaleUpButton.clicked.connect(scaleup)
        hlay1.addWidget(self.ScaleUpButton) 
        self.ScaleDownButton=QtWidgets.QPushButton('ScaleDown')
        hlay1.addWidget(self.ScaleDownButton) 
    
        hlay2 = QtWidgets.QHBoxLayout()
        hlay2.addWidget(QtWidgets.QPushButton('Set Faces')) 
        hlay2.addWidget(QtWidgets.QPushButton('FacePose'))
        hlay2.addWidget(QtWidgets.QPushButton('Gender')) 
        hlay2.addWidget(QtWidgets.QPushButton('Age'))
        hlay2.addWidget(QtWidgets.QPushButton('Recognize'))
    
        layout = QtWidgets.QVBoxLayout()        
        layout.addLayout(hlay1)
        layout.addLayout(hlay2)
        self.horizontalGroupBox.setLayout(layout)
    

    PlayStreading有线程实例,UIWidget有PlayStreading实例(不确定我使用的Python术语是否正确)

    我喜欢寄 self.ScaleUpButton's click signal from UIWidget to scaleup slot in Thread class .

    我该怎么做?

    1 回复  |  直到 7 年前
        1
  •  1
  •   eyllanesc    7 年前

    您必须使用信号和插槽,其思想是每个小部件就像一个黑匣子,因此播放流必须有一个信号,该信号必须调用线程的插槽:

    class Thread(QtCore.QThread):
        changePixmap = QtCore.pyqtSignal(QtGui.QImage)
        def __init__(self, parent=None):
            super(Thread, self).__init__(parent)
            self.scaled_size = QtCore.QSize(640, 480)
            self.curScale=1.0
            self.maxScale = 0
    
        def run(self):
            cap = cv2.VideoCapture(1)
            cap.set(3, 1280);
            cap.set(4, 1024);
            QtCore.QThread.sleep(2)
            maxHeight = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
            self.maxScale = maxHeight/480.0
            while True:
                ret, frame = cap.read()              
                if ret:
                    r=1
                    face_locations=[]
                    rescaleSize=int(480*self.curScale)
                    if(frame.shape[0] > 480 and frame.shape[1] > 640):
                        r = rescaleSize / float(frame.shape[0])
                        dim = (int(frame.shape[1] * r), rescaleSize)
                        face_locations = face_recognition.face_locations(cv2.resize(frame, dim, fx=0.0, fy=0.0))
                    else:
                        face_locations = face_recognition.face_locations(frame)
                    for face_location in face_locations:  
                        top, right, bottom, left = face_location
                        cv2.rectangle(frame,(int(right/r),int(top/r)),(int(left/r),int(bottom/r)),(0,255,0),2)
                    rgbImage = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                    convertToQtFormat = QtGui.QImage(rgbImage.data, rgbImage.shape[1], rgbImage.shape[0], QtGui.QImage.Format_RGB888)
                    p = convertToQtFormat.scaled(self.scaled_size, QtCore.Qt.KeepAspectRatio)
                    self.changePixmap.emit(p)
    
        @QtCore.pyqtSlot(QtCore.QSize)
        def scaled(self, scaled_size):
            self.scaled_size = scaled_size 
    
        @QtCore.pyqtSlot()
        def scaleup(self):
            self.curScale = self.curScale + 0.1
            if self.curScale > self.maxScale:
                self.curScale = self.maxScale
            print(self.curScale)
    
    
    class PlayStreaming(QtWidgets.QLabel):
        reSize = QtCore.pyqtSignal(QtCore.QSize)
        scaleupSignal = QtCore.pyqtSignal()
    
        def __init__(self):
            super(PlayStreaming, self).__init__()
            self.initUI()
    
        @QtCore.pyqtSlot(QtGui.QImage)
        def setImage(self, image):
            self.label.setPixmap(QtGui.QPixmap.fromImage(image))
    
        def initUI(self):
            self.setWindowTitle("Image")
            self.label = QtWidgets.QLabel(self)
            th = Thread(self)
            th.changePixmap.connect(self.setImage)
            self.scaleupSignal.connect(th.scaleup)
            self.reSize.connect(th.scaled)
            th.start()
            lay = QtWidgets.QVBoxLayout(self)
            lay.addWidget(self.label, alignment=QtCore.Qt.AlignCenter)
    
        def resizeEvent(self, event):
            self.reSize.emit(self.size())
    
    
    class UIWidget(QtWidgets.QWidget):
        def __init__(self, parent=None):
            super(UIWidget, self).__init__(parent)
    
            # Initialize tab screen
            self.tabs = QtWidgets.QTabWidget()
            self.tab1 = QtWidgets.QWidget()
            self.tab2 = QtWidgets.QWidget()
            self.tab3 = QtWidgets.QWidget()
    
            # Add tabs
            self.tabs.addTab(self.tab1, "Face")
            self.tabs.addTab(self.tab2, "Human")
            self.tabs.addTab(self.tab3, "Vehicle")
    
            self.display = PlayStreaming()
            # Create first tab
            self.createGridLayout()
            self.tab1.layout = QtWidgets.QVBoxLayout()
            self.tab1.layout.addWidget(self.display, stretch=1)
            self.tab1.layout.addWidget(self.horizontalGroupBox)
            self.tab1.setLayout(self.tab1.layout)
    
            # Add tabs to widget
            layout = QtWidgets.QVBoxLayout(self)
            layout.addWidget(self.tabs)
    
        def createGridLayout(self):
            self.horizontalGroupBox = QtWidgets.QGroupBox("")
            self.horizontalGroupBox.setStyleSheet("QGroupBox{ background-color: red; border: none;}")  
            hlay1 = QtWidgets.QHBoxLayout()
            self.TestButton=QtWidgets.QPushButton('Test')
            hlay1.addWidget(self.TestButton) 
            self.RunButton=QtWidgets.QPushButton('Run')
            hlay1.addWidget(self.RunButton) 
            self.ScaleUpButton=QtWidgets.QPushButton('ScaleUp')
            self.ScaleUpButton.clicked.connect(self.display.scaleupSignal)
            hlay1.addWidget(self.ScaleUpButton) 
            self.ScaleDownButton=QtWidgets.QPushButton('ScaleDown')
            hlay1.addWidget(self.ScaleDownButton) 
    
            hlay2 = QtWidgets.QHBoxLayout()
            hlay2.addWidget(QtWidgets.QPushButton('Set Faces')) 
            hlay2.addWidget(QtWidgets.QPushButton('FacePose'))
            hlay2.addWidget(QtWidgets.QPushButton('Gender')) 
            hlay2.addWidget(QtWidgets.QPushButton('Age'))
            hlay2.addWidget(QtWidgets.QPushButton('Recognize'))
    
            layout = QtWidgets.QVBoxLayout()        
            layout.addLayout(hlay1)
            layout.addLayout(hlay2)
            self.horizontalGroupBox.setLayout(layout)