Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

using QOpenGLWidget as viewPort for QGraphicsView



  • Re: using QOpenGLWidget as viewPort for QGraphicsView in Scene doesn't work?

    I had the same problem mentioned by @davecotter, but by using the graphicsView->setViewport(new QOpenGLWidget()) after the mediaPlayer->setMedia(...) the problem is resolved.
    However, I still have a performance problem in playing video using QGraphicsView and QGraphicsVideoItem. It uses 70% of the CPU to just play a MP4 video (1920x1080).
    While, if I substitute the QGraphicsView with a QVideoWidget, the CPU usage drastically drops to ~6%.
    However, the problem is that I have to use a QGraphicsView to play the video because I need to draw some lines and texts over the video based on the user's mouse clicks.
    My OS is macOS 10.15.7 and I am using PyQt5 version 5.15.2. I would appreciate it if someone please help me to know why there is such a difference between the performance of QVideoWidget and QGraphicsVideoItem.
    Is there any particular setting in the QGraphicsVideoItem to improve its rendering performance?
    It could help me to solve this problem.


  • Lifetime Qt Champion

    Hi,

    What machine are you running ?

    Are you testing that with a minimal application ?



  • Hi,
    Thanks for your reply.
    I am running the application on MacBook Pro (Retina), 2.4 GHz Dual-Core Intel Core i5 processor, 8 GB 1600 MHz DDR3 memory with Intel Iris 1536 MB graphics.
    It is a minimal application that has only a QGaphicsView to play a full HD video.


  • Lifetime Qt Champion

    Do you have a discrete GPU on that machine ?



  • No, I do not have any discrete GPU.



  • This is the sample code I used from https://stackoverflow.com/questions/53899740/how-to-draw-qtgraphicsview-on-top-of-qvideowidget-with-transparency.

    class Widget(QtWidgets.QWidget):
        def __init__(self, parent=None):
            super(Widget, self).__init__(parent)
    
            self._scene = QtWidgets.QGraphicsScene(self)
    
            self._gv = QtWidgets.QGraphicsView(self._scene)
            self._gv.setBackgroundBrush(QtGui.QBrush(QtCore.Qt.lightGray))
    
            self._videoitem = QGraphicsVideoItem() 
            self._scene.addItem(self._videoitem)
    
            self._player = QMediaPlayer(self, QMediaPlayer.VideoSurface)
            self._player.setVideoOutput(self._videoitem.videoSurface())
            file = os.path.join(os.path.dirname(__file__), "GOPR0196.MP4")
            self._player.setMedia(QMediaContent(QtCore.QUrl.fromLocalFile(file)))
    
            button = QtWidgets.QPushButton("Play")
            button.clicked.connect(self.play)
    
            self.resize(640, 480)
            lay = QtWidgets.QVBoxLayout(self)
            lay.addWidget(self._gv)
            lay.addWidget(button)
    
        def play(self):
            oglWidget = QOpenGLWidget()
            self._gv.setViewport(oglWidget)
    
            if self._player.state() == QMediaPlayer.PlayingState:
                self._player.pause()
            else:
                self._player.play()
    
    if __name__ == '__main__':
        import sys
        app = QtWidgets.QApplication(sys.argv)
        w = Widget()
        w.show()
        sys.exit(app.exec_())
    

Log in to reply