diff options
author | Fabian Kosmale <[email protected]> | 2024-11-25 15:57:21 +0100 |
---|---|---|
committer | Fabian Kosmale <[email protected]> | 2025-10-12 17:57:33 +0200 |
commit | d231bd6f735bd8f473bc29079d4608660aaca98e (patch) | |
tree | 3d19dc1744cd2f823ef6e0bca49f7496ebe24615 | |
parent | f41f0607b2df21f979b3a5e5fc866abf9bf488b7 (diff) |
Fix writing undefined via QQmlProperty
Just as with QMetaProperty::write, writing an invalid QVariant should
trigger a RESET function if it exists.
This not only helps with consistency, but will be needed to correctly
handle writes of initial properties when doing more work via
QQmlProperty.
Pick-to: 6.10
Task-number: QTBUG-138825
Change-Id: I77058d292bdea34c0b500e6b61b29bca67ff8d99
Reviewed-by: Ulf Hermann <[email protected]>
-rw-r--r-- | src/qml/qml/qqmlproperty.cpp | 5 | ||||
-rw-r--r-- | tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp | 36 |
2 files changed, 41 insertions, 0 deletions
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index 1829379c34..248f127325 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -1859,6 +1859,11 @@ bool QQmlPropertyPrivate::write( } else { Q_ASSERT(variantMetaType != propertyMetaType); + if (property.isResettable() && !value.isValid()) { + property.resetProperty(object, flags); + return true; + } + bool ok = false; QVariant v; if (variantMetaType == QMetaType::fromType<QString>()) diff --git a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp index 6545298b39..66af07af78 100644 --- a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp +++ b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp @@ -1026,9 +1026,45 @@ struct ComponentWithPublicSetInitial : QQmlComponent } }; +class MyObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(int resettable MEMBER m_resettable RESET resetIt NOTIFY resettableChanged) + void resetIt() { resetCalled = true; } + +public: + MyObject(QObject *parent = nullptr) : QObject(parent) { } + int m_resettable; + bool resetCalled = false; + +signals: + void resettableChanged(); +}; + + void tst_qqmlcomponent::testSetInitialProperties() { QQmlEngine eng; + qmlRegisterType<MyObject>("ResetTest", 1, 0, "MyObject"); + // reset logic + { + QQmlComponent comp(&eng); + comp.loadFromModule("ResetTest", "MyObject"); + std::unique_ptr<QObject> obj {comp.createWithInitialProperties({{u"resettable"_s, QVariant() }}) }; + QVERIFY(obj); + QVERIFY(qobject_cast<MyObject *>(obj.get())->resetCalled); + } + // reset logic - null != undefined + { + QQmlComponent comp(&eng); + comp.loadFromModule("ResetTest", "MyObject"); + QVariant var = QVariant::fromValue(nullptr); + QVERIFY(var.isNull() && var.isValid()); + QTest::ignoreMessage(QtMsgType::QtWarningMsg, QRegularExpression(".*Could not set initial property resettable"_L1)); + std::unique_ptr<QObject> obj {comp.createWithInitialProperties({{u"resettable"_s, var }}) }; + QVERIFY(obj); + QVERIFY(!qobject_cast<MyObject *>(obj.get())->resetCalled); + } { // QVariant ComponentWithPublicSetInitial comp(&eng); |