You need to enable JavaScript to run this app. 使用QPropertyAnimation实现QGraphicsPathItem颜色动画时创建Edge类崩溃求助
优惠活动
大模型
产品
解决方案
定价
更多

使用QPropertyAnimation实现QGraphicsPathItem颜色动画时创建Edge类崩溃求助

QGraphicsPathItem颜色动画实现与崩溃修复

实现QGraphicsPathItem的颜色动画效果,需按照Qt官方文档「图形视图框架的动画机制」章节的指引完成子类化定制。

当需要对QGraphicsItem应用动画效果时,同样可以使用QPropertyAnimation实现。但需注意,QGraphicsItem本身并不继承QObject,可行的解决思路是对需要做动画的图形项进行子类化,让该自定义类同时继承QObject,这样即可将QPropertyAnimation应用于QGraphicsItem,后续示例将演示具体实现方式;另一种可选方案是直接继承本身已属于QObject子类的QGraphicsWidget。
注意:由于Qt元对象系统的要求,继承关系中QObject必须作为第一个被继承的类。

按照上述文档要求编写集成QObject的自定义Edge类后,创建Edge类实例时程序直接崩溃,原始代码如下:

class Edge(QObject, QGraphicsPathItem):

    def __init__(self, point1, point2):
        super().__init__()
        self.point1 = point1
        self.point2 = point2
        self.setPen(QPen(Qt.white, 2, Qt.SolidLine))

    def create_path(self, radius):
        path = QPainterPath()
        path.moveTo(self.point1.x() + radius, self.point1.y() + radius)
        path.lineTo(self.point2.x() + radius, self.point2.y() + radius)

        return path

崩溃根因

  • 代码中仅通过单次super().__init__()完成初始化,按照Python的方法解析顺序,该调用仅会触发排在第一位的QObject类的构造逻辑,完全没有执行QGraphicsPathItem的初始化流程
  • 图形项的底层渲染相关成员未完成初始化,后续调用setPen等图形项原生方法时,会直接触发段错误导致程序崩溃

修正后的可运行实现

  • 多继承场景下不依赖无参super()跨调用父类构造,需显式分别调用两个父类的初始化方法,确保两个基类的逻辑都被完整执行
  • 实现供QPropertyAnimation绑定的颜色属性接口,打通动画驱动的属性更新链路
from PyQt6.QtCore import QObject, pyqtProperty, QPropertyAnimation, QEasingCurve, Qt
from PyQt6.QtGui import QPen, QPainterPath, QColor
from PyQt6.QtWidgets import QGraphicsPathItem

class Edge(QObject, QGraphicsPathItem):
    def __init__(self, point1, point2):
        # 显式完成两个父类的初始化,避免逻辑遗漏
        QObject.__init__(self)
        QGraphicsPathItem.__init__(self)
        
        self.point1 = point1
        self.point2 = point2
        self.setPen(QPen(Qt.GlobalColor.white, 2, Qt.PenStyle.SolidLine))

    # 定义可被动画系统识别的线条颜色属性
    @pyqtProperty(QColor)
    def line_color(self):
        return self.pen().color()

    @line_color.setter
    def line_color(self, color):
        current_pen = self.pen()
        current_pen.setColor(color)
        self.setPen(current_pen)

    def create_path(self, radius):
        path = QPainterPath()
        path.moveTo(self.point1.x() + radius, self.point1.y() + radius)
        path.lineTo(self.point2.x() + radius, self.point2.y() + radius)
        self.setPath(path)
        return path

    def start_color_anim(self, target_color, duration=1000):
        anim = QPropertyAnimation(self, b"line_color")
        anim.setDuration(duration)
        anim.setStartValue(self.line_color)
        anim.setEndValue(target_color)
        anim.setEasingCurve(QEasingCurve.Type.InOutSine)
        # 将动画对象绑定到实例上,避免被垃圾回收导致动画中断
        self._anim = anim
        anim.start()

内容的提问来源于stack exchange,提问作者sirbuandrei

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.27 04:06:08