qt - 转换后如何访问我的自定义 QGraphicsItem 的数据属性的内容
问题描述
我有一个继承自(基本上)的自定义类。一开始我有属性以及相应的getter和setter。一切都很好,直到我从场景中获取项目并尝试调用设置器(或获取器):属性不再存在。所以我对从场景中检索到的元素进行了投射,正如预期的那样......程序崩溃了(因为元素不再存在......我认为)。为了解决这个问题,我使用了基类提供的属性(QGraphicsRectItem
QGraphicsItem
data
QGraphicsItem
) 我认为既然它是一个已经实现的属性,即使在演员表之后我也不应该有任何问题。然而问题依然存在。为什么以及如何解决它?我心中还有其他解决方案,但我想了解为什么这是代表我的问题的简化代码
我的项目.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
解决方案
能失败的就会失败。
所以最好检查一下。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");
}
}
}
推荐阅读
- ms-access - 将参数附加到本地表的访问直通
- kubernetes - Kubernetes 上的 RollingUpdate 不会阻止网关超时
- r - 有没有办法在 R 中使用 rowSums 进行命名子集?
- apache-spark - OutOfMemoryError:过滤多个分区时超出 GC 开销限制
- sql - 如何在不使用 linq include 或其他方式加入的情况下获取应该在另一个表中检查的表数据?
- python - 在 c++ 或 python 中生成一个像样的视差图以在树莓派上实现的最佳方法(算法或函数)是什么?
- android - 分析 ANR 时需要考虑哪些关键字和关键点?
- c# - C#:找不到类型或命名空间名称“DEVMODE”
- android - 教程中的代码现在不起作用
- tfs - TFS 2018 API - 生成 PAT 或 SSH