diff options
-rw-r--r-- | src/qml/qml/qqmlbinding.cpp | 8 | ||||
-rw-r--r-- | src/qml/qml/qqmlbinding_p.h | 1 | ||||
-rw-r--r-- | src/qml/qml/qqmlengine_p.h | 3 | ||||
-rw-r--r-- | src/qml/qml/qqmljavascriptexpression.cpp | 10 | ||||
-rw-r--r-- | tests/auto/qml/bindingdependencyapi/tst_bindingdependencyapi.cpp | 31 |
5 files changed, 52 insertions, 1 deletions
diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index ca4b62ceef..699e5a6daa 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -772,11 +772,17 @@ QVector<QQmlProperty> QQmlBinding::dependencies() const for (int i = 0; i < senderMeta->propertyCount(); i++) { QMetaProperty property = senderMeta->property(i); if (property.notifySignalIndex() == QMetaObjectPrivate::signal(senderMeta, guard->signalIndex()).methodIndex()) { - dependencies.push_back(QQmlProperty(senderObject, QString::fromUtf8(senderObject->metaObject()->property(i).name()))); + dependencies.push_back(QQmlProperty(senderObject, QString::fromUtf8(property.name()))); } } } + for (auto trigger = qpropertyChangeTriggers; trigger; trigger = trigger->next) { + QMetaProperty prop = trigger->property(); + if (prop.isValid()) + dependencies.push_back(QQmlProperty(trigger->target, QString::fromUtf8(prop.name()))); + } + return dependencies; } diff --git a/src/qml/qml/qqmlbinding_p.h b/src/qml/qml/qqmlbinding_p.h index 6ba492f0e4..7c3dab98c2 100644 --- a/src/qml/qml/qqmlbinding_p.h +++ b/src/qml/qml/qqmlbinding_p.h @@ -133,6 +133,7 @@ public: * Call this method from the UI thread. */ QVector<QQmlProperty> dependencies() const; + // This method is used internally to check whether a binding is constant and can be removed virtual bool hasDependencies() const; protected: diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h index 56676d54ee..b3c77dfa83 100644 --- a/src/qml/qml/qqmlengine_p.h +++ b/src/qml/qml/qqmlengine_p.h @@ -75,6 +75,7 @@ #include <QtCore/qmutex.h> #include <QtCore/qstring.h> #include <QtCore/qthread.h> +#include <QtCore/QMetaProperty> #include <private/qobject_p.h> @@ -132,6 +133,8 @@ struct QPropertyChangeTrigger : QPropertyObserver { QObject *target = nullptr; int propertyIndex = 0; static void trigger(QPropertyObserver *, QUntypedPropertyData *); + + QMetaProperty property() const; }; struct TriggerList : QPropertyChangeTrigger { diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp index f25fd0795c..b8b34d2071 100644 --- a/src/qml/qml/qqmljavascriptexpression.cpp +++ b/src/qml/qml/qqmljavascriptexpression.cpp @@ -537,6 +537,16 @@ void QPropertyChangeTrigger::trigger(QPropertyObserver *observer, QUntypedProper This->m_expression->expressionChanged(); } +QMetaProperty QPropertyChangeTrigger::property() const +{ + if (!target) + return {}; + auto const mo = target->metaObject(); + if (!mo) + return {}; + return mo->property(propertyIndex); +} + QPropertyChangeTrigger *QQmlJavaScriptExpression::allocatePropertyChangeTrigger(QObject *target, int propertyIndex) { auto trigger = QQmlEnginePrivate::get(engine())->qPropertyTriggerPool.New( this ); diff --git a/tests/auto/qml/bindingdependencyapi/tst_bindingdependencyapi.cpp b/tests/auto/qml/bindingdependencyapi/tst_bindingdependencyapi.cpp index dfb595ffb0..81162c2c8a 100644 --- a/tests/auto/qml/bindingdependencyapi/tst_bindingdependencyapi.cpp +++ b/tests/auto/qml/bindingdependencyapi/tst_bindingdependencyapi.cpp @@ -48,6 +48,7 @@ private slots: void testConditionalDependencies_data(); void testConditionalDependencies(); void testBindingLoop(); + void testQproperty(); private: bool findProperties(const QVector<QQmlProperty> &properties, QObject *obj, const QString &propertyName, const QVariant &value); @@ -354,6 +355,36 @@ void tst_bindingdependencyapi::testBindingLoop() delete rect; } +void tst_bindingdependencyapi::testQproperty() +{ + QQmlEngine engine; + QQmlComponent c(&engine); + c.setData(QByteArray("import QtQuick 2.0\n" + "Item {\n" + "id: root\n" + "Text {\n" + "id: label\n" + "text: root.x\n" + "}\n" + "}"), QUrl()); + QScopedPointer<QObject> root(c.create()); + QVERIFY(!root.isNull()); + QObject *text = root->findChildren<QQuickText *>().front(); + QVERIFY(text); + auto data = QQmlData::get(text); + QVERIFY(data); + auto b = data->bindings; + QVERIFY(b); + auto binding = dynamic_cast<QQmlBinding*>(b); + QVERIFY(binding); + auto dependencies = binding->dependencies(); + QCOMPARE(dependencies.size(), 1); + auto dependency = dependencies.front(); + QVERIFY(dependency.isValid()); + QCOMPARE(quintptr(dependency.object()), quintptr(root.get())); + QCOMPARE(dependency.property().name(), "x"); +} + QTEST_MAIN(tst_bindingdependencyapi) #include "tst_bindingdependencyapi.moc" |