diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2019-10-09 13:51:33 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2019-10-09 15:59:59 +0200 |
commit | d522746afa394960bef225ba08080d8364b69a7e (patch) | |
tree | 3654d8ff7ca1b263e91c948c36e752fd5e1f53e3 /src/qml/types | |
parent | f1d5b567bd51c23bed686ae648d7c0a0a3e8b0d8 (diff) |
Output a message when changing the target of a Binding from elsewhere
Explicitly created Binding elements should not be silently disabled when
writing their target property. That would be rather confusing. Instead,
the binding stays active and updates the target property again on the
next change.
This behavior is still somewhat confusing. Therefore, if the
qt.qml.binding.removal logging category is enabled, output a helpful
message.
Fixes: QTBUG-78566
Change-Id: Idcd8e51e1cd7eaf78d70b15f065fd9159521ff20
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/types')
-rw-r--r-- | src/qml/types/qqmlbind.cpp | 51 | ||||
-rw-r--r-- | src/qml/types/qqmlbind_p.h | 3 |
2 files changed, 51 insertions, 3 deletions
diff --git a/src/qml/types/qqmlbind.cpp b/src/qml/types/qqmlbind.cpp index 7ab854dad0..921d60caa1 100644 --- a/src/qml/types/qqmlbind.cpp +++ b/src/qml/types/qqmlbind.cpp @@ -54,11 +54,14 @@ #include <QtCore/qfile.h> #include <QtCore/qdebug.h> #include <QtCore/qtimer.h> +#include <QtCore/qloggingcategory.h> #include <private/qobject_p.h> QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(lcBindingRemoval) + class QQmlBindPrivate : public QObjectPrivate { public: @@ -72,6 +75,7 @@ public: , restoreBinding(true) , restoreValue(false) , restoreModeExplicit(false) + , writingProperty(false) {} ~QQmlBindPrivate() { } @@ -90,6 +94,7 @@ public: bool restoreBinding:1; bool restoreValue:1; bool restoreModeExplicit:1; + bool writingProperty: 1; void validate(QObject *binding) const; void clearPrev(); @@ -242,7 +247,7 @@ void QQmlBind::setObject(QObject *obj) } d->obj = obj; if (d->componentComplete) { - d->prop = QQmlProperty(d->obj, d->propName, qmlContext(this)); + setTarget(QQmlProperty(d->obj, d->propName, qmlContext(this))); d->validate(this); } eval(); @@ -288,7 +293,7 @@ void QQmlBind::setProperty(const QString &p) } d->propName = p; if (d->componentComplete) { - d->prop = QQmlProperty(d->obj, d->propName, qmlContext(this)); + setTarget(QQmlProperty(d->obj, d->propName, qmlContext(this))); d->validate(this); } eval(); @@ -401,6 +406,19 @@ void QQmlBind::setRestoreMode(RestorationMode newMode) void QQmlBind::setTarget(const QQmlProperty &p) { Q_D(QQmlBind); + + if (Q_UNLIKELY(lcBindingRemoval().isInfoEnabled())) { + if (QObject *oldObject = d->prop.object()) { + QMetaProperty prop = oldObject->metaObject()->property(d->prop.index()); + if (prop.hasNotifySignal()) { + QByteArray signal('2' + prop.notifySignal().methodSignature()); + QObject::disconnect(oldObject, signal.constData(), + this, SLOT(targetValueChanged())); + } + } + p.connectNotifySignal(this, SLOT(targetValueChanged())); + } + d->prop = p; } @@ -415,7 +433,7 @@ void QQmlBind::componentComplete() Q_D(QQmlBind); d->componentComplete = true; if (!d->prop.isValid()) { - d->prop = QQmlProperty(d->obj, d->propName, qmlContext(this)); + setTarget(QQmlProperty(d->obj, d->propName, qmlContext(this))); d->validate(this); } eval(); @@ -509,7 +527,34 @@ void QQmlBind::eval() QQmlPropertyPrivate::removeBinding(d->prop); } + d->writingProperty = true; d->prop.write(d->value.value.toVariant()); + d->writingProperty = false; +} + +void QQmlBind::targetValueChanged() +{ + Q_D(QQmlBind); + if (d->writingProperty) + return; + + if (d->when.isValid() && !d->when) + return; + + QUrl url; + quint16 line = 0; + + const QQmlData *ddata = QQmlData::get(this, false); + if (ddata && ddata->outerContext) { + url = ddata->outerContext->url(); + line = ddata->lineNumber; + } + + qCInfo(lcBindingRemoval, + "The target property of the Binding element created at %s:%d was changed from " + "elsewhere. This does not overwrite the binding. The target property will still be " + "updated when the value of the Binding element changes.", + qPrintable(url.toString()), line); } QT_END_NAMESPACE diff --git a/src/qml/types/qqmlbind_p.h b/src/qml/types/qqmlbind_p.h index ba040d2a0b..7bf4fc4dfd 100644 --- a/src/qml/types/qqmlbind_p.h +++ b/src/qml/types/qqmlbind_p.h @@ -115,6 +115,9 @@ protected: private: void prepareEval(); void eval(); + +private Q_SLOTS: + void targetValueChanged(); }; QT_END_NAMESPACE |