PyQt5 OpenGL Issue with versionFunctions

Phil Thompson phil at riverbankcomputing.com
Sun Jun 16 14:05:44 BST 2024


On 10/06/2024 13:57, Ognyan Moore wrote:
> Hi Phil,
> 
> A PyQtGraph contributor ran into a PyQt5 issue involving opengl
> context.versionFunctions().
> 
> From what they can tell, the version only manifests itself for
> QOpenGLWidget used as a viewport to QGraphicsView.  If two (or more)
> QGraphicsItem separately store the result of versionFunctions(), all 
> except
> one of the returned versionFunctions() instances will get deleted.
> 
> The behavior is as expected on PyQt6.
> 
> Here is a script to reproduce the issue:
> 
> from PyQt5 import QtCore, QtGui, QtWidgets, sip
> # from PyQt6 import QtCore, QtGui, QtWidgets, sip
> 
> if QtCore.PYQT_VERSION < 0x60000:
>     QtOpenGLWidgets = QtWidgets
> else:
>     from PyQt6 import QtOpenGLWidgets, QtOpenGL
> 
> class MyItem(QtWidgets.QGraphicsRectItem):
>     def __init__(self, *args, **kwargs):
>         super().__init__(*args, **kwargs)
>         self.context = None
>         self.glfn = None
> 
>     def paint(self, painter, option, widget):
>         context = widget.context()
>         if context is not self.context:
>             self.context = context
>             if QtCore.PYQT_VERSION < 0x60000:
>                 profile = QtGui.QOpenGLVersionProfile()
>                 profile.setVersion(2, 0)
>                 self.glfn = context.versionFunctions(profile)
>             else:
>                 profile = QtOpenGL.QOpenGLVersionProfile()
>                 profile.setVersion(2, 0)
>                 self.glfn =
> QtOpenGL.QOpenGLVersionFunctionsFactory.get(profile, context)
> 
>         # print(self.context, self.glfn)
>         print(sip.isdeleted(self.glfn))
>         color = QtCore.Qt.GlobalColor.red if sip.isdeleted(self.glfn) 
> else
> QtCore.Qt.GlobalColor.green
>         self.setBrush(QtGui.QBrush(color))
>         super().paint(painter, option, widget)
> 
> app = QtWidgets.QApplication([])
> gview = QtWidgets.QGraphicsView()
> gview.resize(400, 400)
> scene = QtWidgets.QGraphicsScene()
> gview.setScene(scene)
> viewport = QtOpenGLWidgets.QOpenGLWidget()
> gview.setViewport(viewport)
> 
> rect1 = MyItem(0, 0, 100, 100)
> scene.addItem(rect1)
> rect2 = MyItem(0, -100, 100, 100)
> scene.addItem(rect2)
> 
> gview.show()
> app.exec()
> 
> The output on PyQt6 when running is:
> 
> False
> False
> False
> False
> False
> False
> 
> The output on PyQt5 when running is:
> 
> False
> False
> True
> False
> True
> False
> 
> The resulting image is different to highlight the issue as well.
> 
> Let me know if there is additional information I can provide.
> 
> Thanks,
> Ogi

This may just be the behaviour of Qt5 related to the fact that Qt 
retains ownership of the functions object and seems to be deleting it 
for some reason.

If you don't cache 'context' and 'glfn' in the instance then it works 
fine for both Qt5 and Qt6.

Phil


More information about the PyQt mailing list