首页 > 解决方案 > 转换后如何访问我的自定义 QGraphicsItem 的数据属性的内容

问题描述

我有一个继承自(基本上)的自定义类。一开始我有属性以及相应的getter和setter。一切都很好,直到我从场景中获取项目尝试调用设置器(或获取器):属性不再存在。所以我对从场景中检索到的元素进行了投射,正如预期的那样......程序崩溃了(因为元素不再存在......我认为)。为了解决这个问题,我使用了基类提供的属性(QGraphicsRectItemQGraphicsItemdataQGraphicsItem) 我认为既然它是一个已经实现的属性,即使在演员表之后我也不应该有任何问题。然而问题依然存在。为什么以及如何解决它?我心中还有其他解决方案,但我想了解为什么这是代表我的问题的简化代码

我的项目.h

#ifndef MYITEM_H
#define MYITEM_H

#include <QGraphicsRectItem>
#include <QGraphicsTextItem>
#include <QObject>
#include <QDebug>

class MyItem :public QObject, public QGraphicsRectItem
{
    Q_OBJECT
public:
    enum {Type = UserType + 200};
    MyItem();
    QString getTestProperty() const;
    void setTestProperty(QString p_newValue);
private:
    QGraphicsTextItem* test_txt;
};

#endif // MYITEM_H

我的项目.cpp

#include "myitem.h"

MyItem::MyItem(): QGraphicsRectItem(0,0,100,100)
{
    setFlag(QGraphicsItem::ItemIsMovable);
    test_txt = new QGraphicsTextItem(this);
    setData(0,QVariant("hi there"));
}

void MyItem::setTestProperty(QString p_newValue) {
    setData(0,p_newValue);
    qDebug()<<data(0).toString()<<endl;
    test_txt->setPlainText(data(0).toString());
}
QString MyItem::getTestProperty() const {
    return  data(0).toString();
}

主窗口.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QtDebug>

#include <myitem.h>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private:
    QGraphicsScene* m_scene;
    QGraphicsView* m_view;
};
#endif // MAINWINDOW_H

主窗口.cpp

#include "mainwindow.h"

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 :)");

    MyItem* supposedPointerToItem1 = new MyItem;
    supposedPointerToItem1 = qgraphicsitem_cast<MyItem*> (m_scene->items().first());
    supposedPointerToItem1->setTestProperty("Another test that may fail");//Failed

}

MainWindow::~MainWindow()
{
}

最后这是我得到的结果的截图

The program ended suddenly

在此处输入图像描述

标签: qtcrashqgraphicsitem

解决方案


能失败的就会失败。

所以最好检查一下。QGraphicsScene::items() 返回所有项目,因此它也将返回 QGraphicsTextItem,这就是您的情况:第一个项目不是 MyItem,而是 QGraphicsTextItem。

另一方面,您不必要地创建了第二个 MyItem,而且我认为不需要使用 Q_OBJECT 或从 QObject 继承。

#ifndef MYITEM_H
#define MYITEM_H

#include <QGraphicsRectItem>

class QGraphicsTextItem;

class MyItem :public QGraphicsRectItem
{
public:
    enum {Type = QGraphicsItem::UserType + 200};
    MyItem(QGraphicsItem *parent = nullptr);
    QString getTestProperty() const;
    void setTestProperty(const QString &p_newValue);
    int type() const override;
private:
    QGraphicsTextItem* test_txt;
};

#endif // MYITEM_H
#include "myitem.h"

#include <QDebug>

MyItem::MyItem(QGraphicsItem *parent): QGraphicsRectItem(0,0,100,100, parent)
{
    setFlag(QGraphicsTextItem::ItemIsMovable);
    test_txt = new QGraphicsTextItem(this);
    setData(0,QVariant("hi there"));
}

void MyItem::setTestProperty(const QString & p_newValue) {
    setData(0,p_newValue);
    qDebug()<<data(0).toString();;
    test_txt->setPlainText(data(0).toString());
}

QString MyItem::getTestProperty() const {
    return  data(0).toString();
}

int MyItem::type() const
{
    return Type;
}
#include "mainwindow.h"
#include "myitem.h"

#include <QGraphicsScene>
#include <QGraphicsView>

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 :)");

    QList<QGraphicsItem*> items = m_scene->items();
    for(QGraphicsItem *item : qAsConst(items)){
        if(MyItem* myitem = qgraphicsitem_cast<MyItem *>(item)){
            myitem->setTestProperty("Another test that may fail");
        }
    }
}

推荐阅读