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

