2012-07-09 5 views
4

PySide에서 새로운 QMovie "공급자"를 만드는 방법에 대해 올바른 방향을 알려줄 수 있습니까?PySide를 사용하여 QLabel에 비디오 스트림 표시

가능한 한 간단하게 표시하려는 비디오 스트림이 있습니다 (오디오가없고 알 수없는 프레임 속도의 프레임 시퀀스). This example은 내 동영상이 비 전형적인 소스에서 온다는 점을 제외하고는 완벽하게 보입니다. 파일이 아니지만 표준화되지 않은 형식의 네트워크 스트림입니다. 각 프레임을받는 코드를 쉽게 작성할 수 있으며, 위의 예제와 같이 레이블에이 스트림을 표시 할 수 있도록 "QMovie 공급자"를 만드는 것이 좋습니다.

내 첫 번째 생각은 QMovie를 하위 클래스로 덮어서 거기 몇 가지 기능을 덮어 쓰는 것이 었습니다. 그러나 읽을 때 을 읽는 것에 대한 두 번째 생각을 시작했습니다. 내 인스턴스가 읽는 "장치"에 대해 무엇을해야하는지 모르기 때문입니다. .

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