mrk_brn
mrk_brn

Reputation: 39

Qt C++, save to file an hash of structures

This is an example of my header file:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

//// spare classes
class Foo {
public:
    Foo() {}

    int a;
    QString b;
};

class Bar {
public:
    Bar() {}
    int c;
    QString d;
    QHash<QString, Foo> e;
};

//// widget
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
    QHash<QString, Bar> database;

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

In the main widget class I have a database which is an hash with QString as key and a Bar object as value. The Bar class contains another hash with QString as key and a Foo object as value.

I would like to save the database into a binary file. Reading around I saw that I should use QByteArray and QDataStream, but having objects in the hash instead of simple variables is taking me crazy.

Upvotes: 0

Views: 546

Answers (1)

Alexander Medvidov
Alexander Medvidov

Reputation: 376

QDataStream also may serialize QHash if you define >> and << for your custom types. Simple example:

#include <QtCore>

class Foo {

public:
    Foo() {}

    int a;
    QString b;
};

QDataStream &operator<<(QDataStream &ds, const Foo &obj)
{
   ds << quint32(obj.a) << obj.b;
   return ds;
}

QDataStream &operator>>(QDataStream &ds, Foo &obj)
{
    Foo foo;
    ds >> foo.a >> foo.b;
    obj = foo;
    return ds;
}

class Bar {

public:
    Bar() {}

    int c;
    QString d;
    QHash<QString, Foo> e;

};

QDataStream &operator<<(QDataStream &ds, const Bar &obj)
{
    ds << quint32(obj.c) << obj.d << obj.e;
    return ds;
}

QDataStream &operator>>(QDataStream &ds, Bar &obj)
{
    Bar bar;
    ds >> bar.c >> bar.d >> bar.e;
    obj = bar;
    return ds;
}

int main(int argc, char *argv[])
{    
    QFile db("db.bin");

    if (argc < 2) {
        Foo foo;
        foo.a = 128;
        foo.b = "foo";

        Bar bar;
        bar.c = 255;
        bar.d = "bar";
        bar.e["foo"] = foo;

        QHash<QString, Bar> database;
        database["bar"] = bar;

        if (db.open(QIODevice::WriteOnly)) {
            QDataStream serialize_stream(&db);
            serialize_stream << database;
        } else {
            qDebug() << db.errorString();
        }
    } else {
        if (db.open(QIODevice::ReadOnly)) {
            QDataStream serialize_stream(&db);

            QHash<QString, Bar> database;
            serialize_stream >> database;

            qDebug() << database["bar"].c;
            qDebug() << database["bar"].d;
            qDebug() << database["bar"].e["foo"].a;
            qDebug() << database["bar"].e["foo"].b;
        } else {
            qDebug() << db.errorString();
        }
    }
}

Upvotes: 1

Related Questions