Dejwi
Dejwi

Reputation: 4487

Derives from QSettings and store QIcon

I tried to store QIcon using class, which derives from QSettings as follows:

setValue("fancy_icon", QIcon::fromTheme("document-new"));

but I've got an error:

QVariant::save: unable to save type 69.

And it doesn't work. Surprisingly if I just construct an QSettings instance and save any of 69 type(QIcon) element - it works fine.

QSettings set;
set.setValue("foo", QIcon());
setValue("fancy_icon", QIcon::fromTheme("document-new"));

The question is - why now it works? How can I do it better?

Upvotes: 1

Views: 437

Answers (1)

Amartel
Amartel

Reputation: 4286

Made some digging through Qt's sources.

In qvariant.cpp the only place, where unable to save type error calls is here:

if (!QMetaType::save(s, d.type, constData())) {
    Q_ASSERT_X(false, "QVariant::save", "Invalid type to save");
    qWarning("QVariant::save: unable to save type %d.", d.type);
}

So I went to QMetaType::save:

bool QMetaType::save(QDataStream &stream, int type, const void *data)
{
    ...
    case QMetaType::QPalette:
    case QMetaType::QIcon:
    case QMetaType::QImage:
    ...
        if (!qMetaTypeGuiHelper)
            return false;
        qMetaTypeGuiHelper[type - FirstGuiType].saveOp(stream, data);
        break;
    ...
    return true;
}

qMetaTypeGuiHelper is declared like this:

Q_CORE_EXPORT const QMetaTypeGuiHelper *qMetaTypeGuiHelper = 0;  

Obviously, in your case qMetaTypeGuiHelper equals zero. So I decided to find, where it is created. And found in QtGui module:

static const QVariant::Handler *qt_guivariant_last_handler = 0;
int qRegisterGuiVariant()
{
    qt_guivariant_last_handler = QVariant::handler;
    QVariant::handler = &qt_gui_variant_handler;
    qMetaTypeGuiHelper = qVariantGuiHelper;
    return 1;
}
Q_CONSTRUCTOR_FUNCTION(qRegisterGuiVariant)

int qUnregisterGuiVariant()
{
    QVariant::handler = qt_guivariant_last_handler;
    qMetaTypeGuiHelper = 0;
    return 1;
}
Q_DESTRUCTOR_FUNCTION(qUnregisterGuiVariant)

This means, that in order to save QIcon to QVariant you just need to call qRegisterGuiVariant();. But this function is already called in QApplicationPrivate::initialize(), which, is called from QApplicationPrivate::construct, which is called (whew, what a long list...) from QApplication::QApplication(int &argc, char **argv)

So I have to ask, in your main function, do you create QApplication instance?

P.S: That was fun :)

Upvotes: 5

Related Questions