1

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?

Dejwi
  • 4,393
  • 12
  • 45
  • 74
  • You could convert the icon to a pixmap and call save() on that to store it on disk. The question is, why do you want that? The icon is already stored somewhere in the system and that's where it belongs. – Frank Osterfeld May 17 '13 at 17:17

1 Answers1

5

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 :)

Amartel
  • 4,248
  • 2
  • 15
  • 21