Получается из QSettings и хранит QIcon

Я попытался сохранить QIcon, используя класс, производный от QSettings, следующим образом:

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

но у меня ошибка:

QVariant::save: невозможно сохранить тип 69.

И это не работает. Удивительно, если я просто создаю экземпляр QSettings и сохраняю любой элемент типа 69 (QIcon) - он работает нормально.

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

Вопрос - почему сейчас это работает? Как я могу сделать это лучше?


person Dejwi    schedule 17.05.2013    source источник
comment
Вы можете преобразовать значок в растровое изображение и вызвать для него save(), чтобы сохранить его на диске. Вопрос в том, зачем вам это? Иконка уже хранится где-то в системе и там ей самое место.   -  person Frank Osterfeld    schedule 17.05.2013


Ответы (1)


Немного покопался в исходниках Qt.

В qvariant.cpp единственное место, где unable to save type вызывает ошибку, находится здесь:

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);
}

Итак, я пошел к 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 объявляется так:

Q_CORE_EXPORT const QMetaTypeGuiHelper *qMetaTypeGuiHelper = 0;  

Очевидно, что в вашем случае qMetaTypeGuiHelper равно нулю. Вот я и решил найти, где он создается. И нашел в модуле QtGui:

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)

Это означает, что для сохранения QIcon в QVariant достаточно позвонить qRegisterGuiVariant();. Но эта функция уже вызывается в QApplicationPrivate::initialize(), которая вызывается из QApplicationPrivate::construct, которая вызывается (фух, какой длинный список...) из QApplication::QApplication(int &argc, char **argv)

Поэтому я должен спросить, в вашей функции main вы создаете экземпляр QApplication?

P.S. Было весело :)

person Amartel    schedule 17.05.2013