[PyQt] [Regression] QSGGeometry crash with PyQt 5.5

Phil Thompson phil at riverbankcomputing.com
Sun Aug 2 17:15:22 BST 2015


On 27/07/2015 1:25 pm, Arjen Hiemstra wrote:
> So it took some fiddling, but I managed to reduce it to a fairly
> simple test case, which is attached to this mail.
> 
> Along the way, I discovered a few things:
> 
> * If I never store the new paint node, geometry and material, I get a
> crash as soon as the item should be rendered with PyQt 5.5. With PyQt
> 5.4 it just never shows up.

I think you were just lucky not to get a crash with PyQt v5.4.

> * If I create the new paint node as a function-local variable, then
> just before returning store them as member variables, everything
> works.
> * If I create the paint node as member variable, the first time
> updatePaintNode is called, everything works. As soon as I call
> update() on the item however, things crash.

I think if you take the approach of letting Qt handle the ownership 
issues and only creating new objects when needed things seem to work. 
Something like...

     def updatePaintNode(self, paint_node, update_data):
         if paint_node is None:
             paint_node = QSGGeometryNode()
             
paint_node.setFlags(QSGNode.OwnsGeometry|QSGNode.OwnsMaterial)

             geometry = 
QSGGeometry(QSGGeometry.defaultAttributes_Point2D(), 4, 6)
             geometry.setDrawingMode(QSGGeometry.GL_TRIANGLES)
             geometry.vertexDataAsPoint2D()[0].set(0, 0)
             geometry.vertexDataAsPoint2D()[1].set(0, self.height())
             geometry.vertexDataAsPoint2D()[2].set(self.width(), 
self.height())
             geometry.vertexDataAsPoint2D()[3].set(self.width(), 0)

             geometry.indexDataAsUShort()[0] = 0
             geometry.indexDataAsUShort()[1] = 1
             geometry.indexDataAsUShort()[2] = 3

             geometry.indexDataAsUShort()[3] = 1
             geometry.indexDataAsUShort()[4] = 2
             geometry.indexDataAsUShort()[5] = 3

             paint_node.setGeometry(geometry)

             material = QSGFlatColorMaterial()

             paint_node.setMaterial(material)

         paint_node.material().setColor(self._color)
         paint_node.markDirty(QSGNode.DirtyMaterial)

         return paint_node

There may still be issues but I'm not yet sufficiently familiar with 
scenegraph internals to be sure.

Phil


More information about the PyQt mailing list