我正在尝试序列化一个自定义类
我目前正在尝试像这样测试
现在,正如您在这里看到的,我正在将
我的第二个问题是: 如何正确反序列化数据? 以下是我当前如何序列化单个
首先,我认为在这种情况下将序列化指针并不是我应该做的事情,但我不确定还有什么其他方法或更好的方法。其次,反序列化在这里起作用,但它并没有完全按照我的期望进行。虽然我在重载运算符中使用了设置器,但它实际上并没有正确更新层。我需要调用构造函数来创建一个新的层。
我尝试过这个:Qt中的序列化,但我不太确定如何让
然后将
另外,如何将其反序列化为
我已经想到了一个中间值持有者类的想法,我将使用它来序列化各种图层,并根据图层类型创建和注入参数,但我不确定是否有效。
感谢您的帮助。
Layer*
,并使用QDataStream读取它。现在,Layer
是一个抽象类,具有虚拟方法,被不同类型的层继承:RasterLayer
,TextLayer
,AdjustmentLayer
等。
我有一个QList<Layer*> layers
,用于跟踪所有图层,并更新对图层进行的任何调整。我需要将QList序列化和反序列化到其原始状态,并恢复各个类型的图层的属性。
这是layer.h:
#ifndef LAYER_H
#define LAYER_H
#include <QString>
#include <QImage>
#include <QDebug>
#include <QListWidgetItem>
#include <QGraphicsItem>
#include <QPixmap>
class Layer : public QListWidgetItem
{
public:
enum LayerType{
RASTER,
VECTOR,
TEXT,
ADJUSTMENT
};
Layer(QString name, LayerType type);
~Layer();
inline void setName(QString &name) { _name = name; }
inline QString getName() { return _name; }
inline LayerType getType() { return _type; }
virtual void setSceneSelected(bool select) = 0;
virtual void setLayerSelected(bool select) = 0;
virtual void setZvalue(int z) = 0;
virtual void setParent(QGraphicsItem *parent) = 0;
protected:
QString _name;
LayerType _type;
};
#endif // LAYER_H
这是由 RasterLayer 类扩展的:
#ifndef RASTERLAYER_H
#define RASTERLAYER_H
#include <QGraphicsPixmapItem>
#include <QPainter>
#include <QGraphicsScene>
#include "layer.h"
class RasterLayer : public Layer, public QGraphicsPixmapItem
{
public:
RasterLayer(const QString &name, const QImage &image);
RasterLayer();
~RasterLayer();
void setLocked(bool lock);
void setSceneSelected(bool select);
void setLayerSelected(bool select);
void setZvalue(int z);
void setParent(QGraphicsItem *parent);
inline QPixmap getPixmap() const { return pixmap(); }
inline QPointF getPos() const { return QGraphicsPixmapItem::pos(); }
inline void setLayerPos(QPointF pos) { setPos(pos);}
inline void setLayerPixmap(QPixmap pixmap) { setPixmap(pixmap); }
friend QDataStream& operator<<(QDataStream& ds, RasterLayer *&layer)
{
ds << layer->getPixmap() << layer->getName() << layer->getPos();
return ds;
}
friend QDataStream& operator>>(QDataStream& ds, RasterLayer *layer)
{
QString name;
QPixmap pixmap;
QPointF pos;
ds >> pixmap >> name >> pos;
layer->setName(name);
layer->setPixmap(pixmap);
layer->setPos(pos);
return ds;
}
protected:
void paint(QPainter *painter,
const QStyleOptionGraphicsItem *option,
QWidget *widget);
private:
QImage _image;
};
#endif // RASTERLAYER_H
我目前正在尝试像这样测试
RasterLayer
的串行化-反串行化:
QFile file(fileName);
file.open(QIODevice::WriteOnly);
QDataStream out(&file);
Layer *layer = paintWidget->getItems().at(1);
// Gets the second element in the list
RasterLayer *raster = dynamic_cast<RasterLayer*> (layer);
out << raster;
file.close();
现在,正如您在这里看到的,我正在将
Layer*
特定转换为RasterLayer*
进行序列化,这是有效的,因为我目前只处理了一种类型的图层。所以我的第一个问题是:
如何将此序列化过程推广到所有类型的图层?
每种类型的图层都会有不同的序列化方式,因为它们各自具有不同的属性。此外,在这里进行强制转换似乎有点代码异味和可能是糟糕的设计选择。因此,期望的情况是类似于序列化整个图层列表,调用它们对应的重载运算符。我的第二个问题是: 如何正确反序列化数据? 以下是我当前如何序列化单个
RasterLayer
:QFile newFile(fileName);
newFile.open(QIODevice::ReadOnly);
QDataStream in(&newFile);
RasterLayer *layer2 = new RasterLayer;
in >> layer2;
paintWidget->pushLayer(layer2);
ui->layerView->updateItems(paintWidget->getItems());
首先,我认为在这种情况下将序列化指针并不是我应该做的事情,但我不确定还有什么其他方法或更好的方法。其次,反序列化在这里起作用,但它并没有完全按照我的期望进行。虽然我在重载运算符中使用了设置器,但它实际上并没有正确更新层。我需要调用构造函数来创建一个新的层。
我尝试过这个:Qt中的序列化,但我不太确定如何让
Layer*
将其转换为Layer
,对其进行序列化、反序列化,然后再将其转换回Layer*
。所以我需要添加第三步:RasterLayer *layer3 = new RasterLayer(layer2->getName(), layer2->getPixmap().toImage());
layer3->setPos(layer2->pos());
然后将
layer3
推送到列表中以使其实际工作。根据这篇文章:https://stackoverflow.com/a/23697747/6109408,我真的不应该在运算符重载函数中使用new RasterLayer...
(否则我会下地狱),而我正在遵循那里给出的第一个建议,但在我的情况下它并没有起作用,我不知道正确的方法。另外,如何将其反序列化为
Layer*
的通用QList,而不是必须创建新的特定图层实例并注入反序列化数据?虽然这类似于:Serialize a class with a Qlist of custom classes as member (using QDataStream),但答案并不清楚,我无法理解。我已经想到了一个中间值持有者类的想法,我将使用它来序列化各种图层,并根据图层类型创建和注入参数,但我不确定是否有效。
感谢您的帮助。
QList<Layer*>
重载运算符并进行迭代。 - twodee