aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlobjectcreator.cpp
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2020-09-22 10:48:23 +0200
committerFabian Kosmale <fabian.kosmale@qt.io>2020-10-12 17:50:07 +0200
commita243f1eeeb9eda237ea2f6dad403984ab14aa375 (patch)
tree3ded380bfe0f1293263403d2676a3e3db0709160 /src/qml/qml/qqmlobjectcreator.cpp
parent7750609d8850f6b36317b6243db77b3fe98fd841 (diff)
Fix QProperty property interaction with aliases
With this change, an alias of a bindable property is also bindable, and shares its bindable interface with the target. Moreover, the logic in QQmlTypeCompiler is adjusted so that a change handler of an alias uses the bindable interface if possible, instead of connecting to the alias' change signal. That would never be emitted if the target is a QProperty without a notify signal. Alias properties still have a change signal, but those never get emitted. Change-Id: I857dfdbe51048a2b604ad632982e7f4adac6b907 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/qml/qml/qqmlobjectcreator.cpp')
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp16
1 files changed, 15 insertions, 1 deletions
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 45c9400934..43c639ce8d 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -890,10 +890,24 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper
_scopeObject, runtimeFunction, currentQmlContext());
if (bindingProperty->isBindable()) {
+ auto target = _bindingTarget;
+ if (bindingProperty->isAlias()) {
+ // If the property is an alias, we cannot obtain the bindable interface directly with qt_metacall
+ // so instead, we resolve the alias to obtain the actual target
+ // This should be faster than doing a detour through the metaobject of the target, and relying on
+ // QMetaObject::metacall doing the correct resolution
+ QQmlPropertyIndex originalIndex(bindingProperty->coreIndex(), _valueTypeProperty ? _valueTypeProperty->coreIndex() : -1);
+ QQmlPropertyIndex propIndex;
+ QQmlPropertyPrivate::findAliasTarget(target, originalIndex, &target, &propIndex);
+ QQmlData *data = QQmlData::get(target);
+ Q_ASSERT(data && data->propertyCache);
+ bindingProperty = data->propertyCache->property(propIndex.coreIndex());
+ }
auto &observer = QQmlData::get(_scopeObject)->propertyObservers.emplace_back(expr);
QUntypedBindable bindable;
void *argv[] = { &bindable };
- _bindingTarget->qt_metacall(QMetaObject::BindableProperty, bindingProperty->coreIndex(), argv);
+ target->qt_metacall(QMetaObject::BindableProperty, bindingProperty->coreIndex(), argv);
+ Q_ASSERT(bindable.isValid());
bindable.observe(&observer);
} else {
QQmlBoundSignal *bs = new QQmlBoundSignal(_bindingTarget, signalIndex, _scopeObject, engine);