pyqt5:qMainWindow不会扩展到centralWidget大小

时间:2015-09-25 12:20:25

标签: python opencv video-processing pyqt5

我正在使用pyqt5将openCV 3.0与Qt5在Python 3.4.3中集成。我一直在尝试构建一个应用程序来处理来自文件的视频,但是遇到了pyqt的麻烦。具体来说,我将多次通过文件对话框加载视频,这些视频的大小不一样。因此,我希望我的应用程序中的主窗口包装/扩展到正在播放的视频的大小。

下面是我的代码的简化版本,其中包含用于显示视频的3个核心类。一个用于主窗口,一个用于框架查看器窗口小部件以显示GUI中的每个视频帧,一个用于视频处理器通过opencv读取和处理视频,将其转换为QImage然后将其发送给查看器。

class videoProcessor(QtCore.QObject):
    filename = None
    cap = None    

    videoSignal = QtCore.pyqtSignal(QtGui.QImage)

    def __init__(self):
        super().__init__()
        self.filename = "test.mp4"

    @QtCore.pyqtSlot()
    def runVideoProcessor(self):
        self.cap = cv2.VideoCapture(self.filename)

        while self.cap.isOpened():
            ret, frame = self.cap.read()
            if ret:
                outimg = cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)
                imgh, imgw, bytesPerComponent = outimg.shape
                bytesPerLine = bytesPerComponent * imgw;
                qtimg = QtGui.QImage(outimg.data,imgw,imgh,bytesPerLine,QtGui.QImage.Format_RGB888)
                self.videoSignal.emit(qtimg)
            else:
                break    
        self.cap.release()

class frameViewer(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.image = QtGui.QImage()
        self.imageAvailable = False

    def paintEvent(self,event):
        painter = QtGui.QPainter(self)
        painter.drawImage(0,0,self.image)
        self.image = QtGui.QImage()
        painter.end()

    @QtCore.pyqtSlot(QtGui.QImage)
    def setFrame(self,image):
        self.image = image
        self.setFixedSize(self.image.size())
        self.repaint()

class mainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.fview = frameViewer()
        self.vproc = videoProcessor()
        self.vproc.videoSignal.connect(self.fview.setFrame)

        self.startButton = QtWidgets.QPushButton("Start")
        self.startButton.clicked.connect(self.vproc.runVideoProcessor)

        self.mainLayout = QtWidgets.QVBoxLayout()
        self.mainLayout.addWidget(self.fview)
        self.mainLayout.addWidget(self.startButton)

        self.mainWidget = QtWidgets.QWidget()
        self.mainWidget.setLayout(self.mainLayout)
        self.mainWidget.setSizePolicy(QtWidgets.QSizePolicy.Expanding,QtWidgets.QSizePolicy.Expanding)
        self.setCentralWidget(self.mainWidget)

        self.statusBar().showMessage('Ready')
        self.setGeometry(50, 50, 300, 300)
        self.setWindowTitle('OpenCV PyQt Test')    
        self.show()

if __name__=='__main__':
    app = QtWidgets.QApplication(sys.argv)
    mw = mainWindow()
    sys.exit(app.exec_())

到目前为止,该程序可以运行视频,但有两个主要问题:

  1. 在视频结束之前,窗口不会调整到视频帧的大小。但是,相同视频播放的任何重复都将具有正确的大小。
  2. 如果我在绘制图像后未在self.image=QtGui.QImage()中设置paintEvent程序崩溃。但是,如果我将该行放入视频末尾,则窗口将变为空白,因为每当窗口更新时,将在最后一帧的位置绘制空QImage
  3. 有关如何解决这些问题的任何想法?谢谢。

0 个答案:

没有答案