我有一个用Python编写的GUI应用程序,我正在尝试在Qt应用程序中显示视频。
它使用QGraphicsScene和QGraphicsView来显示图像,但现在我必须显示一个视频。当我尝试在这里播放视频时,我就是这样做的:
首先,我从cv2包创建VideoCapture。之后,我在每次迭代中运行循环和读取帧,然后将其转换为QPixmap(这是正确完成的,我检查了一个帧)。我将QPixmap对象返回到包含QGraphicsScene和QGraphicsView的类,并尝试将其添加到场景中。
事情是,只有当视频结束时,才会显示最后一帧,在整个视频播放时间内我都会受到这种目击的欢迎
我之前提到的循环如下所示:
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)
我希望我能清楚地解决问题并包含所需的所有代码。
答案 0 :(得分: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()