序列化QGraphicsScene内容
我正在使用Qt QGraphicsScene
类,添加了预定义的项目,如QGraphicsRectItem
, QGraphicsLineItem
等,我想将场景内容序列化到磁盘。 然而,基础QGraphicsItem
类(即我使用的其他项目)不支持序列化,所以我需要推出我自己的代码。 问题是所有对这些对象的访问都是通过一个基本的QGraphicsItem
指针,所以我的序列化代码是可怕的:
QGraphicsScene* scene = new QGraphicsScene;
scene->addRect(QRectF(0, 0, 100, 100));
scene->addLine(QLineF(0, 0, 100, 100));
...
QList<QGraphicsItem*> list = scene->items();
foreach (QGraphicsItem* item, items)
{
if (item->type() == QGraphicsRectItem::Type)
{
QGraphicsRectItem* rect = qgraphicsitem_cast<QGraphicsRectItem*>(item);
// Access QGraphicsRectItem members here
}
else if (item->type() == QGraphicsLineItem::Type)
{
QGraphicsLineItem* line = qgraphicsitem_cast<QGraphicsLineItem*>(item);
// Access QGraphicsLineItem members here
}
...
}
这是不好的代码恕我直言。 所以,我可以创建一个ABC类,像这样:
class Item
{
public:
virtual void serialize(QDataStream& strm, int version) = 0;
};
class Rect : public QGraphicsRectItem, public Item
{
public:
void serialize(QDataStream& strm, int version)
{
// Serialize this object
}
...
};
然后我可以使用QGraphicsScene::addItem(new Rect(,,,));
添加Rect对象QGraphicsScene::addItem(new Rect(,,,));
但是这并不能真正帮助我,因为以下将会崩溃:
QList<QGraphicsItem*> list = scene->items();
foreach (QGraphicsItem* item, items)
{
Item* myitem = reinterpret_class<Item*>(item);
myitem->serialize(...) // FAIL
}
任何方式,我可以使这项工作?
我同意其他海报,QGraphicsItem可以真正被视为一个视图项目,因此将你的模型数据分成它自己的类可能会更好。
这就是说,我认为你的崩溃是由不适当的演员造成的。
如果您执行以下操作:
Rect *r = new Rect();
QGraphicsItem *qi = reinterpret_cast<QGraphicsItem*>(r);
QGraphicsRectItem *qr = reinterpret_cast<QGraphicsRectItem*>(r);
Item *i = reinterpret_cast<Item*>(r);
qDebug("r = %p, qi = %p, qr = %p, i = %p", r, qi, qr, i);
你应该看到r == qi,r == qr,但r!= i。 如果考虑如何在内存中表示一个继承乘数的对象,那么第一个基类是内存中的第一个,第二个基类是第二个,等等。 所以指向第二个基类的指针将被偏移第一个基类的大小[大约]。
所以要修复你的代码,我认为你需要做一些事情:
QList<QGraphicsItem*> list = scene->items();
foreach (QGraphicsItem* item, items)
{
Rect* myrect = reinterpret_class<Rect*>(item); // needed to figure out the offset to the Item part
Item* myitem = reinterpret_class<Item*>(myrect);
myitem->serialize(...);
}
这是很多原因之一,我希望尽可能避免多重继承。 正如先前建议的那样,我强烈建议您将模型数据分开。
序列化QGraphicsItem
不是一个好主意。 一个QGrahpicsScene
应该代表你的数据。 不要序列化表示,最好序列化应用程序的数据/模型。
如果你想记录图形实体的排列,也许你可以使用自定义的QGraphicsItem
并绘制成一个QPicture。
如果你真的想序列化这些项目创建
QDataStream &operator<<(QDataStream &, const AppropriateSubclass&);
QDataStream &operator>>(QDataStream &, AppropriateSubclass&);
对于您想要序列化的每个QGraphicsItem
子类,这些函数都是非成员函数。 该方法也在QDataStream文档中进行了解释
但是我支持斯蒂芬的回答,你可能想考虑将实际数据拖出场景并将其放入单独的模型类中
链接地址: http://www.djcxy.com/p/46323.html上一篇: Serializing QGraphicsScene contents
下一篇: Libraries and pseudocode for physical Dashboard/Status board