使用PySide在QLabel中显示视频流

时间:2012-07-09 18:43:27

标签: python pyqt pyside qpixmap qlabel

有人能指出我如何在PySide中创建新的QMovie“提供者”吗?

我想要尽可能简单地显示视频流(没有音频,只有一系列具有未知和可变帧速率的帧)。除了我的视频来自非常规来源之外,This example看起来很完美。它不是文件,而是非标准化格式的网络流。我可以轻松编写接收每个帧的代码,我的想法是创建一个“QMovie提供者”,这样我就可以在上面的例子中的标签上显示这个流。

我的第一个想法就是将QMovie子类化并覆盖那里的一些函数但我在阅读the documentation时开始对此有了第二个想法,因为我不知道我应该怎么做关于“设备”我的实例会正在阅读。

我在前面提到的文档中注意到QMovie使用QImageReader所以我的下一个想法是扩展该类并让它从我的流中读取帧。然而,这会产生类似的问题,例如,我应该怎么处理“supportedImageFormats()”函数?

我每次收到一个新的框架时都在尝试直接更新QLabel上的图像,但后来我得到了错误“QPixmap:在GUI线程外使用pixmaps是不安全的。” / p>

所以基本上我有点难过,非常感谢有关如何让QLabel在PySide应用程序中显示我的视频流的任何指针或教程。

1 个答案:

答案 0 :(得分:9)

为了将来参考我是如何设法让这个工作的。

使用信号和插槽机制,以下应用程序可以正常工作。信号/插槽机制似乎弄清楚在up_camera_callback函数内创建并发送到CameraDisplay.updateFrame函数的图像来自不同的线程并采取必要的预防措施。

class CameraDisplay(QtGui.QLabel):
  def __init__(self):
    super(CameraDisplay, self).__init__()

  def updateFrame(self, image):
    self.setPixmap(QtGui.QPixmap.fromImage(image))

class ControlCenter(QtGui.QWidget):
  up_camera_signal = QtCore.Signal(QtGui.QImage)
  up_camera = None

  def __init__(self):
    super(ControlCenter, self).__init__()
    self.up_camera = CameraDisplay()
    self.up_camera_signal.connect(self.up_camera.updateFrame)

    grid = QtGui.QGridLayout()
    grid.setSpacing(10)

    grid.addWidget(self.up_camera, 0, 0)

    self.setLayout(grid)

    self.setGeometry(300, 300, 350, 300)
    self.setWindowTitle('Control Center')
    self.show()

  def up_camera_callback(self, data):
    '''This function gets called by an external thread'''
    try:
      image = QtGui.QImage(data.data, data.width, data.height, QtGui.QImage.Format_RGB888)
      self.up_camera_signal.emit(image)

    except Exception, e:
      print(e)

if __name__ == "__main__":
  app = QtGui.QApplication(sys.argv)
  ex = ControlCenter()
  sys.exit(app.exec_())