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

4
我想将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的枚举类型中找不到它,也没有值1030。Q_DECLARE_METATYPE(QList<int>);没有效果。
这里出了什么问题?还是应该使用typeName(),因为它返回正确的类型名称而不是type()
Qt 5.13.1,clang 8.0.1,Linux 64位。

1
这只是一个观察结果:如果只包括“core”或“gui”模块,我得到的是:“QVariant :: QList <int> | QList <int> | 1024 | QList <int>”,但如果添加“widgets”,我会得到:“QVariant :: QWidget * | QList <int> | 1025 | QWidget *”。 - eyllanesc
它只是简单地返回最后一个注册的QMetaType(1024是"用户"范围的起点)。这也是肯定会引起困惑的另一点。 - Maxim Paperno
1个回答

3

QList<T>并不是一个预定义的变体类型(除了QList<QVariant>),因此在技术上它被解析为QMetaType::UserType。这有点复杂难懂,而且肯定取决于哪些Qt模块已经包含在内(元类型系统是设计成可以通过这种方式扩展的--例如,没有GUI模块,你就无法使用任何这些类型)。

所以...实际上是QMetaType“知道”底层自定义类型。从给定的例子中,QVariant::typeToName(v.userType())正确地打印出QList<int>。我发现QVariant::userType()始终返回实际元类型,而只有type()似乎相当无用(即使文档试图解释它的工作原理,也会让人感到困惑)。

为了增加混淆,QVariant::Type似乎已经被弃用了...如果你在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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接