You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义QGraphicsItem类型转换后如何访问data属性及修复崩溃问题

问题根因

  1. qgraphicsitem_cast转换失败导致空指针解引用:Qt的qgraphicsitem_cast要正确识别自定义QGraphicsItem子类,必须在子类中重写从QGraphicsItem继承的虚函数type()。你只在MyItem类中定义了Type枚举,没有实现对应的type()虚函数,因此转换逻辑无法识别当前item是MyItem类型,转换结果直接返回nullptr,后续调用setTestProperty属于空指针解引用,直接触发程序崩溃。你使用基类data属性仍然出问题,本质也是因为指针为空,没有指向任何合法对象,和属性本身无关。
  2. 冗余内存分配(非崩溃直接原因,但属于代码错误):MyItem* supposedPointerToItem1 = new MyItem; 属于完全多余的写法,你后续立刻用qgraphicsitem_cast的返回值覆盖了该指针,刚分配的对象没有被释放,造成内存泄漏。
  3. 缺少安全校验:没有对转换后的指针、场景返回的item列表做判空校验,即使转换逻辑正确,一旦场景为空或者类型不匹配,也会触发异常。

修复方案

步骤1:在MyItem类中添加type()虚函数的实现

修改MyItem.h的public部分,添加重写逻辑:

class MyItem :public QObject, public QGraphicsRectItem
{
    Q_OBJECT
public:
    enum {Type = UserType + 200};
    // 新增下面这行,重写type虚函数
    int type() const override {
        return Type;
    }
    MyItem();
    QString getTestProperty() const;
    void setTestProperty(QString p_newValue);
private:
    QGraphicsTextItem* test_txt;
};

步骤2:修正MainWindow中的错误代码

删除冗余的内存分配,添加空指针校验:

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    setMinimumSize(800,600);
    m_scene = new QGraphicsScene;
    m_view = new QGraphicsView;
    m_view->setScene(m_scene);

    MyItem* item1 = new MyItem();
    m_scene->addItem(item1);
    setCentralWidget(m_view);
    item1->setTestProperty("hello there :)");

    // 删除冗余的new操作,直接接收转换结果
    MyItem* supposedPointerToItem1 = qgraphicsitem_cast<MyItem*> (m_scene->items().first());
    // 增加判空逻辑,避免空指针解引用
    if (supposedPointerToItem1) {
        supposedPointerToItem1->setTestProperty("Another test that may fail");
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 03:09:04