2016-05-16 224 views
1

我有一个我在Python中编写的GUI应用程序,我试图在Qt应用程序中显示视频。试图在QGraphicsScene和QGraphicsView中显示opencv视频,但没有显示

它使用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的正确ammount的,但它并不能帮助一个组成部分。

的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

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

我会做这样的事情:

def grabFrame 
    retVal = self.imageViewer.read_frame() 
    if not retVal: 
     self.timer.stop() 
     self.imageViewer.stop_capturing() 
在你的主逻辑

而且某处或你的一些类的初始化函数:

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()