QVariant中的QList,QVariant :: type()返回奇怪的类型

时间:2019-09-29 18:27:47

标签: c++ qt qvariant

我试图将QList<int>存储在QVariant中,然后进行类型检查以确定存储在QVariant中的值的确切类型(用于序列化)。 QVariant::type()在标量类型如intQString上可以很好地工作,但这就是我在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*甚至来自哪里?我在QVariant的enum Type中找不到它,也没有值1030。Q_DECLARE_METATYPE(QList<int>);没有任何作用。

这是怎么了?还是应该使用typeName(),因为它返回正确的类型名称而不是type()

Qt 5.13.1,clang 8.0.1,Linux 64位

1 个答案:

答案 0 :(得分:2)

QList<T>实际上不是预定义的变体类型(QList<QVariant>除外),因此从技术上讲它解析为QMetaType::UserType。这有点令人费解,并且肯定取决于所包含的Qt模块(元类型系统设计为可通过这种方式扩展-例如,没有GUI模块,则没有任何可用的这些类型)。

因此...实际上是QMetaType“了解”底层自定义类型。在给定的示例中,QVariant::typeToName(v.userType())正确地打印了QList<int>。我发现QVariant::userType()总是返回实际的元类型,而type()似乎毫无用处(即使文档很费劲,也试图解释它的工作原理)。

更令人困惑的是,QVariant::Type似乎已被弃用...如果单击docs for type()中的“ QVariant :: 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