在 PyQt 中更新 Qt 场景图

Posted

技术标签:

【中文标题】在 PyQt 中更新 Qt 场景图【英文标题】:Updating Qt Scene Graph in PyQt 【发布时间】:2017-08-07 21:55:27 【问题描述】:

我已经在 PyQt5 中运行了Qt scenegraph tutorial。好消息是我得到了贝塞尔曲线,正如承诺的那样。更好的是,当我调整窗口大小时,会添加一条新的贝塞尔曲线以匹配新的窗口大小。问题是旧的贝塞尔曲线仍然存在。如何让 Qt 仅绘制最近的几何图形?

这是我在教程中的绘图代码的端口

def updatePaintNode(self, oldNode, _):
    if not oldNode:
        node = QSGGeometryNode()
        geometry = QSGGeometry(QSGGeometry.defaultAttributes_Point2D(),
                               self._segment_count)
        geometry.setLineWidth(2)
        geometry.setDrawingMode(QSGGeometry.DrawLineStrip)
        node.setGeometry(geometry)
        node.setFlag(QSGNode.OwnsGeometry)
        material = QSGFlatColorMaterial()
        material.setColor(QColor(255, 0, 0))
        node.setMaterial(material)
        node.setFlag(QSGNode.OwnsMaterial)
    else:
        node = oldNode
        geometry = node.geometry()
        geometry.allocate(self._segment_count)

    vertices = geometry.vertexDataAsPoint2D()

    for i in range(self._segment_count):
        t = float(i)/(self._segment_count-1)
        invt = 1-t

        pos = invt * invt * invt * self._p1 \
              + 3 * invt * invt * t * self._p2 \
              + 3 * invt * t * t * self._p3 \
              + t * t * t * self._p4 \


        x = pos.x() * self.width()
        y = pos.y() * self.height()

        vertices[i].set(x, y)

    node.markDirty(QSGNode.DirtyGeometry)

    return node

【问题讨论】:

你不检查 - 如果oldNode 在调整大小后为空? @folibis 我在 oldNode 上检查 null 的唯一地方是上面的第二行。我应该为调整大小实施单独的处理程序吗? 【参考方案1】:

我不确定这是不是最好的答案,但我偶然发现了一个解决方法。我使几何节点成为更通用节点的子节点,这似乎解决了问题。第一个条件现在看起来像:

    if not oldNode:
        node3 = QSGGeometryNode()
        node = QSGNode()
        node.appendChildNode(node3)

        geometry = QSGGeometry(QSGGeometry.defaultAttributes_Point2D(), self._segment_count)
        geometry.setLineWidth(2)
        geometry.setDrawingMode(QSGGeometry.DrawLineStrip)
        node3.setGeometry(geometry)
        node3.setFlag(QSGNode.OwnsGeometry)
        material = QSGFlatColorMaterial()
        material.setColor(QColor(255, 0, 0))
        node3.setMaterial(material)
        node3.setFlag(QSGNode.OwnsMaterial)
    else:
        node = oldNode
        geometry = node.firstChild().geometry()
        geometry.allocate(self._segment_count)

由于我仍然不确定我在做什么或为什么这有效,所以我还没有接受这个答案。如果知道自己在做什么的人想要提供更好的答案,我很乐意接受。不过,我也想记录下我自己的解决方案,以防其他人遇到此问题。

【讨论】:

以上是关于在 PyQt 中更新 Qt 场景图的主要内容,如果未能解决你的问题,请参考以下文章

将纹理添加到 QT OpenGL 场景图

PyQT QGraphicScene 在后台线程中移动项目

为啥不更新重绘场景?

qt获取滚动视图位置

调用 Python 对象进行连续场景更新时超出最大递归深度

PyQt5 旋转像素图