Details
-
Bug
-
Resolution: Done
-
P3: Somewhat important
-
5.3.2
-
None
Description
It is possible to convert from a QMap<QString, T> to a QVariantMap or a QVariantHash via QVariant::value(), where T is a user-chosen type which is a metatype. The conversion uses a custom converter.
If T is QVariant, the type is a QVariantMap, which is a built-in metatype. That means there is no user-specified converter.
That means that if a QVariant contains a QMap<QString, int>, then var.value<QVariantHash>() works, but if it contains a QVariantMap, then var.value<QVariantHash>() does not work.
QVariantValueHelperInterface<QVariantHash> and QVariantValueHelperInterface<QVariantMap> only check for user-defined converters, but should also check if the contained type is exactly a built-in metatype.
QVariantValueHelperInterface<QVariantList> already has such a check for built-ins, so it does not exhibit a comparable bug.
QMap<QString, int> mp; QVariantMap varmp; mp.insert("3", 4); varmp.insert("3", 4); QStringList li; li.append("Hello"); QVariantList varli; varli.append("World"); QVariant var; var = QVariant::fromValue(li); qDebug() << var.value<QVariantList>(); var = QVariant::fromValue(varli); qDebug() << var.value<QVariantList>(); var = QVariant::fromValue(mp); qDebug() << var.value<QVariantHash>(); var = QVariant::fromValue(varmp); qDebug() << var.value<QVariantHash>(); qDebug() << QMetaType::hasRegisteredConverterFunction(qMetaTypeId<QVariantList>(), qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>()); qDebug() << QMetaType::hasRegisteredConverterFunction(qMetaTypeId<QStringList>(), qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>()); qDebug() << QMetaType::hasRegisteredConverterFunction(qMetaTypeId<QVariantHash>(), qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>()); qDebug() << QMetaType::hasRegisteredConverterFunction(qMetaTypeId<QVariantMap>(), qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>()); qDebug() << QMetaType::hasRegisteredConverterFunction(qMetaTypeId<QMap<int, int> >(), qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>()); qDebug() << QMetaType::hasRegisteredConverterFunction(qMetaTypeId<QHash<QString, int> >(), qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>());
Output
(QVariant(QString, "Hello") ) (QVariant(QString, "World") ) QHash(("3", QVariant(int, 4) ) ) QHash() false false false false true true
Attachments
For Gerrit Dashboard: QTBUG-41403 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
97743,6 | Fix QVariant associative container conversion from built-in types. | 5.4 | qt/qtbase | Status: MERGED | +2 | 0 |
123169,2 | Avoid recreating QVariantLists when extracted from a QVariant | 5.6 | qt/qtbase | Status: MERGED | +2 | 0 |