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 2.1k 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.
  • 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 Online
      JonBJ Online
      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