2012-07-09 2 views
4

me point Quelqu'un peut-il dans la bonne direction sur la façon de créer un nouveau « fournisseur » de QMovie dans PySide?Affichage d'un flux vidéo en QLabel avec PySide

J'ai un flux vidéo que je veux montrer le plus simplement possible (pas de son, juste une séquence d'images avec un framerate inconnu et variable). This example semble parfait sauf que ma vidéo provient d'une source non conventionnelle. Ce n'est pas un fichier mais un flux réseau dans un format qui n'est pas standardisé. Je peux facilement écrire du code qui reçoit chaque image et mon idée est de créer un "fournisseur QMovie" pour que je puisse simplement afficher ce flux sur une étiquette comme dans l'exemple ci-dessus. Ma première pensée a été de simplement sous-classer QMovie et d'y écraser quelques fonctions, mais j'ai commencé à avoir des doutes à ce sujet en lisant the documentation car je ne sais pas ce que je devrais faire du "périphérique" que mon instance lirait .

J'ai vu dans la documentation ci-dessus que QMovie utilise QImageReader donc ma pensée suivante était d'étendre cette classe et l'ont lu des cadres de mon flux. Cela pose cependant des questions similaires, par exemple, que dois-je faire avec la fonction "supportedImageFormats()"? J'ai expérimenté avec juste mettre à jour directement l'image sur mon QLabel chaque fois que je reçois un nouveau cadre, mais alors j'ai reçu l'erreur "QPixmap: Il est dangereux d'utiliser des pixmaps en dehors du thread graphique".

Donc, fondamentalement, je suis un peu perplexe et aimerait l'avoir des pointeurs ou des tutoriels sur la façon d'obtenir un QLabel pour afficher mon flux vidéo dans une application PySide.

Répondre

8

Pour référence future est ici que je réussi à obtenir ce travail.

en utilisant les signaux et le mécanisme de fente, la demande suivante fonctionne. Le mécanisme signal/slot semble comprendre que l'image créée à l'intérieur de la fonction up_camera_callback et émise à la fonction CameraDisplay.updateFrame provient d'un thread différent et prend les précautions nécessaires.

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 pour le suivi des générations futures ... – neuronet