QML: Don't try to convert objects with prototypes to QVariant

This is likely to lose some properties.

Pick-to: 6.5
Fixes: QTBUG-106266
Change-Id: Ib5a2567d61635a5cf7b3abee7cfef0c073d59e63
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Ulf Hermann 2023-05-05 14:59:37 +02:00
parent ee2154dbfe
commit 4307755655
4 changed files with 31 additions and 4 deletions

View File

@ -1711,10 +1711,7 @@ static QVariant objectToVariant(const QV4::Object *o, V4ObjectSet *visitedObject
} }
result = list; result = list;
} else if (const FunctionObject *f = o->as<FunctionObject>()) { } else if (o->getPrototypeOf() == o->engine()->objectPrototype()->d()) {
// If it's a FunctionObject, we can only save it as QJSValue.
result = QVariant::fromValue(QJSValuePrivate::fromReturnedValue(f->asReturnedValue()));
} else {
QVariantMap map; QVariantMap map;
QV4::Scope scope(o->engine()); QV4::Scope scope(o->engine());
QV4::ObjectIterator it(scope, o, QV4::ObjectIterator::EnumerableOnly); QV4::ObjectIterator it(scope, o, QV4::ObjectIterator::EnumerableOnly);
@ -1732,6 +1729,9 @@ static QVariant objectToVariant(const QV4::Object *o, V4ObjectSet *visitedObject
} }
result = map; result = map;
} else {
// If it's not a plain object, we can only save it as QJSValue.
result = QVariant::fromValue(QJSValuePrivate::fromReturnedValue(o->asReturnedValue()));
} }
visitedObjects->remove(o->d()); visitedObjects->remove(o->d());

View File

@ -0,0 +1,10 @@
import QtQml 2.15
QtObject {
id: root
Component.onCompleted: {
let comp = Qt.createComponent("dynamic.qml");
let inst = comp.createObject(root, { testObj: new Set(), });
objectName = inst.use();
}
}

View File

@ -0,0 +1,6 @@
import QtQml
QtObject {
property var testObj
function use() { return testObj.has(1) ? 25 : 26; }
}

View File

@ -146,6 +146,7 @@ private slots:
void loadFromModuleRequired(); void loadFromModuleRequired();
void loadFromQrc(); void loadFromQrc();
void removeBinding(); void removeBinding();
void complexObjectArgument();
private: private:
QQmlEngine engine; QQmlEngine engine;
@ -1450,6 +1451,16 @@ void tst_qqmlcomponent::removeBinding()
QCOMPARE(o->property("result"), QStringLiteral("42")); QCOMPARE(o->property("result"), QStringLiteral("42"));
} }
void tst_qqmlcomponent::complexObjectArgument()
{
QQmlEngine e;
QQmlComponent c(&e, testFileUrl("complexObjectArgument.qml"));
QVERIFY2(c.isReady(), qPrintable(c.errorString()));
QScopedPointer<QObject> o(c.create());
QVERIFY(!o.isNull());
QCOMPARE(o->objectName(), QStringLiteral("26"));
}
QTEST_MAIN(tst_qqmlcomponent) QTEST_MAIN(tst_qqmlcomponent)
#include "tst_qqmlcomponent.moc" #include "tst_qqmlcomponent.moc"