QList в QVariant, QVariant :: type () возвращает странный тип - PullRequest
3 голосов
/ 29 сентября 2019

Я пытаюсь сохранить QList<int> в QVariant, а затем выполнить проверку типов, чтобы определить точный тип значения, хранящегося в QVariant (для сериализации). QVariant::type() отлично работает со скалярными типами, такими как int или QString, но вот что я получил с QList<int>:

QList<int> list{1,2,3};
QVariant v = QVariant::fromValue<QList<int>>(list);
qDebug() << v.type() << "|" << v.typeName() << "|" << v.userType() << "|" << QVariant::typeToName(v.type());

Производит:

QVariant::QWidget* | QList<int> | 1030 | QWidget*

Где этоQVariant::QWidget* даже откуда? Я не могу найти его в enum Type QVariant, ни в значении 1030. Q_DECLARE_METATYPE(QList<int>); не имеет никакого эффекта.

Что здесь не так? Или я должен использовать typeName(), поскольку он возвращает правильное имя типа вместо type()?

Qt 5.13.1, clang 8.0.1, 64-битный Linux

1 Ответ

2 голосов
/ 01 октября 2019

QList<T> на самом деле не предопределенный тип варианта (за исключением QList<QVariant>), поэтому он технически разрешается в QMetaType::UserType. Это немного запутанно, чтобы следовать, и определенно зависит от того, какие модули Qt были включены (система мета-типов разработана таким образом, чтобы быть расширяемой - например, без модуля GUI у вас не было бы ни одного из этих доступных типов).

Итак ... на самом деле QMetaType "знает" о базовых пользовательских типах. Из приведенного примера QVariant::typeToName(v.userType()) печатает QList<int> правильно. Я обнаружил, что QVariant::userType() всегда возвращает фактический метатип, тогда как type() кажется довольно бесполезным (даже документы запутаны, пытаясь объяснить, как это работает).

Чтобы добавить к путанице, QVariant::Type кажется устаревшим ... если вы нажмете ссылку "QVariant :: Type" в документах для type(), она перейдет в раздел "устаревшие члены". Там, где это перечисление даже не указано.

На самом деле QMetaType не "знает" тип QList<int>, пока он не используется (или зарегистрирован). Пример:

    qDebug() << QMetaType::type("QList<int>");  // prints 0
    QList<int> list{1,2,3};
    QVariant v = QVariant::fromValue(list);
    qDebug() << QMetaType::type("QList<int>");  // prints 1028 on my test project, yours may vary

Или, если зарегистрирован специально:

    qDebug() << qRegisterMetaType<QList<int> >("QList<int>");  // prints 1028
    qDebug() << QMetaType::type("QList<int>");  // prints 1028
    QList<int> list{1,2,3};
    QVariant v = QVariant::fromValue(list);
    qDebug() << QMetaType::type("QList<int>");  // still 1028
...