我正在使用opencv3,python 3和pyqt5。我想创建一个简单的GUI,我想在主窗口上单击按钮时打开一个新窗口来播放视频和其他一些小部件。我曾经使用QPixmap
来显示过去的图像,因此我创建了一个标签,并尝试在一个循环中设置像素图中的帧。循环工作正常,但我无法显示视频/新窗口。
我想在新窗口中执行的循环如下所示:
def setupUi():
vid=cv2.VideoCapture('file')
ret, frame=vid.read()
while ret:
Qimg=convert(frame)
self.label.setpixmap(Qimg)
self.label.update()
ret,frame=vid.read()
convert()
是我自己写的一个函数,它将cv帧转换为QImage
类型以设置为像素图。
我只是pyQt的初学者,所以不知道我做错了什么。我已经阅读过有关使用信号,新窗口的线程和QtApplication.processEvents()
的内容,但不知道这些是如何工作的,以及它们如何适应我的问题。
如果有人能够让我朝着正确的方向前进并指出一些资源来为我的应用程序使用OpenCV和python创建良好的界面,那将会很有帮助。
答案 0 :(得分:2)
这个没有运行的原因是你的while循环阻止了Qt的事件循环。基本上,你陷入了while循环,你永远不会把控制权交还给Qt来重绘屏幕。
您的update()调用并不是您认为的那样;它更新了对象存储的数据,但在程序重新进入eventloop之前,此更改不会显示。
可能有多种处理方法,但我看到两个不错的选择,第一个更容易实现:
1)在while循环的每次迭代中调用QApplication.processEvents()。这迫使Qt更新GUI。这比2)实现起来要简单得多。
2)将函数移动到一个单独的类,并使用QThread结合moveToThread()来更新数据,并使用信号/插槽与GUI线程进行通信。这将需要重新调整您的代码,但这可能对您的代码整体有利。现在,生成数据的代码可能在您的MainWindow类中,而两者应根据Qt's Model-View design pattern分开。对于小型一次性应用程序来说不是很重要,但随着应用程序规模的扩大,这将有助于保持代码库的清晰度。