我创建了一个公共QGraphicsItem Node
类,它具有与我的应用程序相关的一堆属性的getter / setter方法。该应用程序是一个图表编辑器,用户可以在其中设计模型。此Node
类用于填充公共QGraphicsScene Diagram
类。
我现在正在尝试在应用程序中实现加载/保存机制,使用户能够保存和重用模型 - 按照保存时的方式对其进行编辑。我在弄清楚如何解决这个问题时遇到了一些麻烦。
我已经知道我必须获取QGraphicsItem对象的相关属性并将它们保存到文件中,然后在加载时,使用我保存的数据重建场景。我的问题是:当我使用QGraphicsScene::items()
函数时,它会返回QList<QGraphicsItem *>
。如果让它返回QList<Node *>
我该怎么办?
如果我得到一个我附加到场景中的所有节点的列表,我知道下一步该做什么。
我开始意识到我可能不得不重新实现items()
课程中的Diagram
功能,但我希望我能更容易地逃脱它。在这种情况下,有人可以解释一下如何做到这一点吗?
答案 0 :(得分:1)
我建议实施QGraphicsItem::type()
方法并使用qgraphicsitem_cast
投射到所需的类中。在您的情况下,您可以从公共基类继承所有自定义GraphicsItem。
你的基类看起来像这样:
class MyGraphicsItem: public QGraphicsItem
{
enum { Type = UserType + 1 };
int type() const { return Type; }
};
您的Node和您的Link类将继承此基础:
class Node : public MyGraphicsItem
{
// ...
};
class Link : public MyGraphicsItem
{
// ...
};
在其他地方,您可以将QGraphicsItem强制转换为基类MyGraphicsItem
,例如:
QList<QGraphicsItem*> allItems = graphicsScene->items();
foreach (QGraphicsItem *item, allItems) {
// Using qgraphicsitem_cast
MyGraphicsItem* graphicsItem = qgraphicsitem_cast<MyGraphicsItem*>(item);
if (graphicsItem) {
// Do something with MyGraphicsItem
}
}
答案 1 :(得分:1)
虽然items函数返回QGraphicsItem指针的列表,但您可以尝试使用dynamic_casting来检查它是否是Node指针,或者使用Qt元数据和type()函数。
然而,我经常使用的方法,也可以在其他方面帮助你,是为每种类型的对象和项目ID的静态列表维护一个唯一的id。例如: -
class BaseItem : public QGraphicsItem
{
public:
BaseItem(QGraphicsItem* parent)
: QGraphicsItem(parent), m_Id(m_NextId++) // initialising the object's unique Id
{
}
unsigned int ID() const
{
return m_Id;
}
private:
static unsigned int m_NextId; // the next Object Id, initialised to 0 in implementation
unsigned int m_Id; // the object's unique Id
}
class Node : public BaseItem
{
public:
Node(QGrahicsItem* parent)
: BaseItem(parent)
{
m_NodesList.push_back(m_Id);
}
private:
static QList<unsigned int> m_sNodesList; // all Node ids in the scene
QList<unsigned int> m_linkedNodeList; // linked nodes
}
添加到GraphicsScene的所有项目都继承自BaseItem
你还有一个Node Ids的静态列表,所以你可以迭代遍历所有这些以进行加载/保存,你可以在基类中添加一个静态帮助函数来返回一个节点列表,通过搜索列表节点ID并将它们与场景中的节点指针相匹配。
此体系结构还允许您在每个Node对象中包含链接节点ID的列表,而不是使用Qt的父/子系统,在节点图的情况下,并不总是需要。< / p>
总的来说,我已经将这个架构用于许多QGraphicsScene应用程序,并且它确实使得开发非常容易用于与其他项目有复杂链接的项目。