Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. QSGGeometry does not work on PySide2
Forum Updated to NodeBB v4.3 + New Features

QSGGeometry does not work on PySide2

Scheduled Pinned Locked Moved Unsolved Qt for Python
16 Posts 5 Posters 1.5k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • SGaistS SGaist

    @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.

    A Offline
    A Offline
    Advig
    wrote on last edited by Advig
    #6

    @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_())
    
    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #7

      Did you open an issue on the bug tracker ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      A 1 Reply Last reply
      0
      • SGaistS SGaist

        Did you open an issue on the bug tracker ?

        A Offline
        A Offline
        Advig
        wrote on last edited by
        #8

        @SGaist . Thanks. Yes. PYSIDE-1345

        1 Reply Last reply
        1
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #9

          Thank you !

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • A Offline
            A Offline
            Advig
            wrote on last edited by
            #10

            @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.

            1 Reply Last reply
            0
            • Y Offline
              Y Offline
              Yossip
              wrote on last edited by
              #11

              I am facing the same issue. This basically makes writing custom QQuickItems in Python impossible.

              Also, I am hitting this issue with PySide6.

              The bug that was reported is stuck nowhere.

              1 Reply Last reply
              0
              • Y Offline
                Y Offline
                Yossip
                wrote on last edited by
                #12

                Quick update. I reviewed the ticket again and realized there is a patch there. I recomplied PySide6 with the patch applied and I can say that vertexDataAsPoint2D() now does return a list of Point2D instead of just Point2D. In the ticket the developer states that the fix crashes submitted example. I am yet to confirm whether this causes any issues on my side.

                1 Reply Last reply
                0
                • Y Offline
                  Y Offline
                  Yossip
                  wrote on last edited by
                  #13

                  Ok, I have the same problem as mentioned in the ticket - it segfaults.

                  To summarize, you cannot write custom QQuickItems in Python at this time.

                  1 Reply Last reply
                  0
                  • SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on last edited by
                    #14

                    Thanks for the feedback !

                    Can you upload your minimal example on the report ?
                    It can help fix this issue as well.

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    1 Reply Last reply
                    0
                    • Y Offline
                      Y Offline
                      Yossip1
                      wrote on last edited by
                      #15

                      Hi SGaist,

                      Here's the code. It's really basic:

                      # This Python file uses the following encoding: utf-8
                      import os
                      from pathlib import Path
                      import sys
                      
                      from PySide6.QtGui import QGuiApplication, QColor
                      from PySide6.QtQml import QQmlApplicationEngine, qmlRegisterType
                      from PySide6.QtQuick import QQuickItem, QSGGeometryNode, QSGGeometry, QSGFlatColorMaterial, QSGNode
                      
                      
                      class JustItem(QQuickItem):
                          def __init__(self, parent=None):
                              super().__init__(parent)
                              self.setFlag(QQuickItem.ItemHasContents, enabled=True)
                      
                      
                          def updatePaintNode(self, node, update_data):
                              if node is None:
                                  node = QSGGeometryNode()
                                  geometry = QSGGeometry(QSGGeometry.defaultAttributes_Point2D(), 4)
                                  geometry.setLineWidth(1)
                                  geometry.setDrawingMode(QSGGeometry.DrawTriangles)
                      
                      
                                  material = QSGFlatColorMaterial()
                                  material.setColor(QColor(255, 0, 0, 127))
                      
                                  node.setGeometry(geometry)
                                  node.setMaterial(material)
                                  node.setFlag(QSGNode.OwnsGeometry)
                                  node.setFlag(QSGNode.OwnsMaterial)
                              else:
                                  geometry = node
                      
                              vertex_data = geometry.vertexDataAsPoint2D()
                      
                              vertex_data[0].set(10, 10)
                              vertex_data[1].set(100, 10)
                              vertex_data[2].set(100, 100)
                              vertex_data[3].set(10, 100)
                              node.markDirty(QSGNode.DirtyGeometry)
                      
                              return node
                      
                      
                      if __name__ == "__main__":
                          qmlRegisterType(JustItem, "PythonTypes", 1, 0, "JustItem")
                      
                          app = QGuiApplication(sys.argv)
                          engine = QQmlApplicationEngine()
                          engine.load(os.fspath(Path(__file__).resolve().parent / "main.qml"))
                      
                      
                          if not engine.rootObjects():
                              sys.exit(-1)
                          sys.exit(app.exec())
                      

                      and main.qml:

                      import QtQuick
                      import QtQuick.Window
                      import PythonTypes 1.0
                      
                      Window {
                          width: 640
                          height: 480
                          visible: true
                          title: qsTr("Hello World")
                      
                          JustItem {
                      
                          }
                      }
                      

                      If you run it without the patch, it will complain that Point2D is not subscriptible (because Point2D and not a list of Point2Ds is returned). If you run it with the patch applied, it will segfault.

                      1 Reply Last reply
                      0
                      • SGaistS Offline
                        SGaistS Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on last edited by
                        #16

                        Thanks for posting it here but you should add it to the bug report as well. It will be easier to find over there.

                        Interested in AI ? www.idiap.ch
                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved