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

QSGGeometry does not work on PySide2

Scheduled Pinned Locked Moved Unsolved Qt for Python
16 Posts 5 Posters 1.4k Views
  • 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.
  • A Offline
    A Offline
    Advig
    wrote on last edited by
    #1

    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

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

      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.

      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
      2
      • A Offline
        A Offline
        Advig
        wrote on last edited by
        #3

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

        JonBJ SGaistS 2 Replies Last reply
        0
        • A Advig

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

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #4

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

          1 Reply Last reply
          0
          • A Advig

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

            SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #5

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

            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

              @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