batuman
batuman

Reputation: 7304

How to change display size changing with window size in PyQT5?

I am displaying webcam image from cv2 on QPixmap.

I have PyQt5 and Python2.7.

Now the issue is the display size doesn't change with Window size.

I like to change image size together with display window size.

Now is always 640x480.

Attached images show image size is fixed. I like to have just slightly smaller than window size and change together with window size.

enter image description here enter image description here

My code is as follow.

from PyQt5 import QtCore, QtGui, QtWidgets 
import cv2

class Thread(QtCore.QThread):
   changePixmap = QtCore.pyqtSignal(QtGui.QImage)
   def run(self):
        cap = cv2.VideoCapture(0)
        while True:
            ret, frame = cap.read()
            if ret:
                print(frame.shape)
                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(640, 480, QtCore.Qt.KeepAspectRatio)
                self.changePixmap.emit(p)


class PlayStreaming(QtWidgets.QWidget):
    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)
        th = Thread(self)
        th.changePixmap.connect(self.setImage)
        th.start()
        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(self.label, alignment=QtCore.Qt.AlignCenter)


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()
        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("Control")
        self.horizontalGroupBox.setStyleSheet("QGroupBox { background-color: red}");
        layout = QtWidgets.QGridLayout()
        layout.addWidget(QtWidgets.QPushButton('Test'),0,0) 
        layout.addWidget(QtWidgets.QPushButton('Run'),0,1) 
        layout.addWidget(QtWidgets.QPushButton('Set Faces'),0,2) 
        layout.addWidget(QtWidgets.QPushButton('Recognize'),1,0) 
        layout.addWidget(QtWidgets.QPushButton('Rescale'),1,1) 
        layout.addWidget(QtWidgets.QPushButton('FacePose'),1,2)
        self.horizontalGroupBox.setLayout(layout)


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = UIWidget()
    w.resize(1000, 800)
    w.show()
    sys.exit(app.exec_())

Upvotes: 1

Views: 6143

Answers (1)

Degang Guo
Degang Guo

Reputation: 505

You can listen to the resize event of PlayStreaming and send the adjusted size to the thread through the signal for scaling.

from PyQt5 import QtCore, QtGui, QtWidgets
import cv2


class Thread(QtCore.QThread):
    changePixmap = QtCore.pyqtSignal(QtGui.QImage)
    scaled_size = QtCore.QSize(640, 480)

    def run(self):
        cap = cv2.VideoCapture(0)
        while True:
            ret, frame = cap.read()
            if ret:
                print(frame.shape)
                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


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)
        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()
        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("Control")
        self.horizontalGroupBox.setStyleSheet("QGroupBox { background-color: red}");
        layout = QtWidgets.QGridLayout()
        layout.addWidget(QtWidgets.QPushButton('Test'), 0, 0)
        layout.addWidget(QtWidgets.QPushButton('Run'), 0, 1)
        layout.addWidget(QtWidgets.QPushButton('Set Faces'), 0, 2)
        layout.addWidget(QtWidgets.QPushButton('Recognize'), 1, 0)
        layout.addWidget(QtWidgets.QPushButton('Rescale'), 1, 1)
        layout.addWidget(QtWidgets.QPushButton('FacePose'), 1, 2)
        self.horizontalGroupBox.setLayout(layout)


if __name__ == '__main__':
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = UIWidget()
    w.resize(1000, 800)
    w.show()
    sys.exit(app.exec_())

Upvotes: 3

Related Questions