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

QSGGeometry does not work on PySide2



  • I am trying to use QSGGeometry from PySide2. In the C++ implementation vertexDataAsPoint2D() return a pointer to the 2d points. Not sure how to access the points from geometry.vertexDataAsPoint2D() in PySide2. In PyQt, the following works,

    vertices = geometry.vertexDataAsPoint2D()
    vertices[1].set(x2, y2)
    

    But in PySide2 this gives an error,
    TypeError: 'PySide2.QtQuick.QSGGeometry.Point2D' object is not subscriptable


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    From the error it seems that you directly get a Point2D object.

    Check the type of the return value of that method.



  • @SGaist , you are right, vertexDataAsPoint2D() returns Point2D. Not sure how this works with PyQt and not on PySide2. From the documentation I understand this function should return a pointer. But pointer in python?



  • @Advig
    Just read it as returning an object/instance in Python.


  • Lifetime Qt Champion

    @Advig it's a binding issue. You should check the bug report system to see if there's already something related. If not please open a new issue. The best would be if you can provided a minimal project that shows the issue.



  • @SGaist
    Thanks. Please find attached the file. Also creating a bug report as advised.
    trying to create Scene Graph - Custom Geometry (https://doc.qt.io/qt-5/qtquick-scenegraph-customgeometry-example.html) in Pyside2, but getting following error :
    File "/BezierCurveProj/main.py", line 119, in updatePaintNode
    vertices[i].set(x, y)
    TypeError: 'PySide2.QtQuick.QSGGeometry.Point2D' object is not subscriptable

    # This Python file uses the following encoding: utf-8
    import sys
    from PySide2.QtWidgets import QApplication
    from PySide2.QtQuick import QQuickView, QQuickItem, QSGNode, QSGGeometryNode, QSGGeometry, QSGMaterialType
    from PySide2.QtCore import Signal, QUrl, Property, QPointF
    from PySide2.QtGui import QColor
    from PySide2.QtQml import qmlRegisterType
    
    
    class BezierCurve(QQuickItem):
        def __init__(self):
            QQuickItem.__init__(self)
            self.m_p1 = QPointF(0, 0)
            self.m_p2 = QPointF(0, 1)
            self.m_p3 = QPointF(1, 0)
            self.m_p4 = QPointF(1, 1)
            self.m_segmentCount = 32
    
            self.node = None
            self.geometry = None
            self.setFlag(QQuickItem.ItemHasContents, True)
    
        @Signal
        def p1Changed(self):
            pass
    
        @Signal
        def p2Changed(self):
            pass
    
        @Signal
        def p3Changed(self):
            pass
    
        @Signal
        def p4Changed(self):
            pass
    
        @Signal
        def segmentCountChanged(self):
            pass
    
        def p1(self):
            return self.m_p1
    
        def p2(self):
            return self.m_p2
    
        def p3(self):
            return self.m_p3
    
        def p4(self):
            return self.m_p4
    
        def segmentCount(self):
            return self.m_segmentCount
    
        def setP1(self, p):
            if (p == self.m_p1):
                return
            self.m_p1 = p
            self.p1Changed.emit()
            self.update()
    
        def setP2(self, p):
            if (p == self.m_p2):
                return
            self.m_p2 = p
            self.p2Changed.emit()
            self.update()
    
        def setP3(self, p):
            if (p == self.m_p3):
                return
            self.m_p3 = p
            self.p3Changed.emit()
            self.update()
    
        def setP4(self, p):
            if (p == self.m_p4):
                return
            self.m_p4 = p
            self.p4Changed.emit()
            self.update()
    
        def setSegmentCount(self, p):
            if (p == self.m_segmentCount):
                return
            self.m_segmentCount = p
            self.segmentCountChanged.emit()
            self.update()
    
        def updatePaintNode(self, oldNode, updatePaintNodeData):
            self.node = oldNode
            if(self.node is None):
                self.node = QSGGeometryNode()
                self.geometry = QSGGeometry(QSGGeometry.defaultAttributes_Point2D(), self.m_segmentCount)
                self.geometry.setLineWidth(2)
                self.geometry.setDrawingMode(QSGGeometry.DrawLineStrip)
                self.node.setGeometry(self.geometry)
                self.node.setFlag = QSGNode.OwnsGeometry
                material = QSGMaterialType()
                material.setColor = QColor(255, 0, 0)
                self.node.setMaterial = material
                self.node.setFlag = QSGNode.OwnsMaterial
                self.geometry.allocate(self.m_segmentCount)
            else:
                self.geometry = self.node.geometry()
                self.geometry.allocate(self.m_segmentCount)
    
            itemSize = self.size()
            vertices = self.geometry.vertexDataAsPoint2D()
            for i in range(self.m_segmentCount):
                t = i / (self.m_segmentCount - 1)
                invt = 1 - t
                pos = (invt * invt * invt * self.m_p1) + (3 * invt * invt * t * self.m_p2) + (3 * invt * t * t * self.m_p3) + (t * t * t * self.m_p4)
                x = pos.x() * itemSize.width()
                y = pos.y() * itemSize.height()
                vertices[i].set(x, y)
    
            self.node.markDirty(QSGNode.DirtyGeometry)
            return self.node
    
        p1 = Property('QPointF', p1, setP1, notify=p1Changed)
        p2 = Property('QPointF', p2, setP2, notify=p2Changed)
        p3 = Property('QPointF', p3, setP3, notify=p3Changed)
        p4 = Property('QPointF', p4, setP4, notify=p4Changed)
        segmentCount = Property('int', segmentCount, setSegmentCount, notify=segmentCountChanged)
    
    
    if __name__ == "__main__":
        app = QApplication([])
        view = QQuickView()
        view.setResizeMode(QQuickView.SizeRootObjectToView)
        qmlRegisterType(BezierCurve, 'BezierCurve', 1, 0, 'BezierCurve')
        url = QUrl("main.qml")
        view.setSource(url)
        view.show()
        sys.exit(app.exec_())
    

  • Lifetime Qt Champion

    Did you open an issue on the bug tracker ?



  • @SGaist . Thanks. Yes. PYSIDE-1345


  • Lifetime Qt Champion

    Thank you !



  • @SGaist : Do you know any easy way I could write a patch for this. I am not sure if I will get a solution soon from bug tracking system.


Log in to reply