Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How To Save Custom Type To QSettings?

Tags:

c++

qt

I'm trying to save a custom type to QSettings but I'm getting an error at runtime. Here's the class I'm trying to save:

#ifndef TESTCLASS_H
#define TESTCLASS_H

#include <QMetaType>
#include <QString>

class TestClass
{
public:
    QString testString;
    int testInt;
    bool testBool;
};

Q_DECLARE_METATYPE(TestClass)

#endif

And here's the code to save an instance of the class to QSettings

TestClass test;
test.testString = "Test";
test.testInt = 10;
test.testBool = false;

settings.setValue("TestGroup/TestVal", QVariant::fromValue(test));
settings.sync();

The error I get at runtime is:

QVariant::save: unable to save type 'TestClass' (type id: 1032).

ASSERT failure in QVariant::save: "Invalid type to save", file kernel\qvariant.cpp, line 2124
Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.

According to the documentation, the class must provide a default constructor, destructor and a copy constructor. For this class the automatically generated constructor, destructor and copy constructors would be sufficient, so I haven't provided one (though I did try it anyway to see if that was the problem). I've also used Q_DECLARE_METATYPE() so the class is known to QMetaType, so as far as I can tell I've met the requirements to use the class with QVariant.

What am I missing?

like image 279
Assoluto Avatar asked May 19 '16 20:05

Assoluto


1 Answers

You have to implement streaming. TestClass should have 2 overloaded operators <<, >>. For instance:

class TestClass
{
public:
    QString testString;
    qint32 testInt;
    friend QDataStream & operator << (QDataStream &arch, const TestClass & object)
    {
        arch << object.testString;
        arch << object.testInt;
        return arch;
    }

    friend QDataStream & operator >> (QDataStream &arch, TestClass & object)
    {
        arch >> object.testString;
        arch >> object.testInt;
        return arch;
    }
};

Q_DECLARE_METATYPE(TestClass)

Before saving instance of TestClass you have to use qRegisterMetaTypeStreamOperators function, like this:

    qRegisterMetaTypeStreamOperators<TestClass>("TestClass");
    QSettings settings(QSettings::IniFormat, QSettings::UserScope,"MySoft", "Star Runner");
    settings.setValue("TestGroup/TestVal", QVariant::fromValue(test));
    settings.sync();
like image 70
arturx64 Avatar answered Nov 04 '22 14:11

arturx64