2012-07-09 108 views
4

任何人都可以指出我如何在PySide中創建一個新的QMovie「提供者」的正確方向?用PySide在QLabel中顯示視頻流

我有一個視頻流,我希望儘可能簡單地顯示(沒有音頻,只是一系列未知和可變幀率的幀)。 This example似乎很完美,只不過我的視頻來自非常規來源。這不是一個文件,而是一個沒有標準化格式的網絡流。我可以輕鬆地編寫接收每幀的代碼,我的想法是創建一個「QMovie提供程序」,以便我可以像上例中那樣在標籤上顯示此流。

我的第一個想法是隻是繼承QMovie並覆蓋了一些函數,但是當我讀the documentation時,我開始有第二個想法,因爲我不知道我應該怎樣處理我的實例將從中讀取的「設備」 。

我在上述文檔中注意到QMovie使用QImageReader,所以我的下一個想法是擴展該類並讓它從我的流中讀取幀。然而,這帶來了類似的問題,例如,我應該如何處理「supportedImageFormats()」函數?

我一直在嘗試與每次我QLabel只是直接更新圖像我收到一個新的框架,但那時我已經得到了錯誤「的QPixmap:這是不是安全使用GUI線程之外的像素圖」。

所以基本上我有點難住,真的很感謝任何關於如何讓QLabel在PySide應用程序中顯示我的視頻流的指針或教程。

回答

8

爲了將來的參考,我設法讓這個工作。

使用信號和插槽機制,以下應用程序工作。信號/插槽機制似乎發現在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_()) 
+0

+1爲跟隨未來世代... – neuronet 2014-06-09 02:43:59