首页 文章

试图在QGraphicsScene和QGraphicsView中显示opencv视频,但没有显示

提问于
浏览
1

我有一个用Python编写的GUI应用程序,我正在尝试在Qt应用程序中显示视频 .

它使用QGraphicsScene和QGraphicsView来显示图像,但现在我必须显示一个视频 . 当我尝试在这里播放视频时,我会这样做:

首先,我从cv2包创建VideoCapture . 之后,我在每次迭代中运行循环和读取帧,然后将其转换为QPixmap(这是正确完成的,我检查了一个帧) . 我将QPixmap对象返回到包含QGraphicsScene和QGraphicsView的类,并尝试将其添加到场景中 .

事情是,只有当视频结束时,才会显示最后一帧,在整个视频播放时间内,我很受欢迎

A blank non responsive screen

我之前提到的循环如下所示:

self.imageViewer.start_capturing()
    self.timer = QtCore.QTimer()
    self.fps = 24

    while True:
        retVal = self.imageViewer.read_frame()
        if not retVal:
            self.timer.stop()
            break
        self.timer.start(1000./self.fps)
    self.imageViewer.stop_capturing()

self.ImageViewer是一个包含QGraphicsScene和QGraphicsView的组件 . 我还在这里放置了计时器,以便它显示正确的fps数量,但它没有帮助 .

GUI应用程序本身使用一些按钮显示QGraphicsView

middleLayout.addWidget(self.imageViewer.view)

这就是我的意思 . 所以它没有显示 imageViewer 但是它显示了 QGraphicsView 的子类

以下是ImageViewer类中read_frame方法的代码 .

def read_frame(self):
    """
    Reads a frame from the video, if video ended, then False is returned.
    If there is a successful reading then True is returned
    :return: True if video is read successfully, False otherwise.
    """
    retVal, self.current_frame = self.capture.getFrame()
    if not retVal:
        return False
    else:
        self.pixmap = retVal
        self.scene.addPixmap(self.pixmap)
        return True

方法 self.capture.getFrame() 只返回QPixmap项和CV :: mat项 .

整个过程正确完成,因为我尝试手动逐帧阅读,一切正常,但当我尝试显示视频时,应用程序冻结如上图所示 . 所以我手动尝试通过手动点击一个加载我框架并将其放到QGraphicsScene上的按钮来完成整个描述的过程,所以我假设应用程序的核心工作正常(我甚至试图通过点击大约5-7 fps)快:D)

我希望我能清楚地解决问题并包含所需的所有代码 .

1 回答

  • 1

    我认为你的计时逻辑是错误的..你没有正确使用计时器..你可以使用connect或者你可以使用睡眠 .

    我会做这样的事情:

    def grabFrame
        retVal = self.imageViewer.read_frame()
        if not retVal:
            self.timer.stop()
            self.imageViewer.stop_capturing()
    

    在你的主逻辑或你的类的一些init函数的某个地方:

    yourObject.connect(timer,SIGNAL("timeout()"),yourObject,SLOT("grabFrame()"))
    timer.start(1000./self.fps)
    

    或者你可以使用某种时间模块的睡眠

    import time
    ...
    while True:
        retVal = self.imageViewer.read_frame()
        if not retVal:
            break
        time.sleep(1./self.fps)//in fraction of second
    self.imageViewer.stop_capturing()
    

相关问题