Normalerweise mache ich dies, indem ich einen Haltepunkt im Qt-Code platziere, der die Warnung ausgibt. Dafür benötigen Sie ein Qt mit Debug-Symbolen.
Suche nach "Binding Loop erkannt" in den Qt-Quellen gibt mir QQmlAbstractBinding::printBindingLoopError(). Wenn Sie dort einen Haltepunkt platzieren, führt dies in der Regel zu einem Backtrace, der ein klares Bild der Situation liefert.
Update: David Edmundson hat ein kleines Tool entwickelt, das eine QML-Backtrace auf Bindungsschleifen anzeigt, siehe his blog here. Unter der Haube tut genau das, was hier beschrieben wird, nur dass es schön automatisiert und in ein Python-Skript eingebunden ist.
Beispiel:
Rectangle {
id: parent
width: child.width + 1
height: child.height + 1
Rectangle {
id: child
anchors.fill: parent
}
}
Backtrace:
1 QQmlAbstractBinding::printBindingLoopError qqmlabstractbinding.cpp 178 0x7ffff6eb36da
2 QQmlBinding::update qqmlbinding.cpp 221 0x7ffff6eb9abe
3 QQmlBinding::update qqmlbinding_p.h 97 0x7ffff6eba354
4 QQmlBinding::expressionChanged qqmlbinding.cpp 260 0x7ffff6eb9e68
5 QQmlJavaScriptExpressionGuard_callback qqmljavascriptexpression.cpp 361 0x7ffff6eb223e
6 QQmlNotifier::emitNotify qqmlnotifier.cpp 94 0x7ffff6e9087a
7 QQmlData::signalEmitted qqmlengine.cpp 763 0x7ffff6e19a45
8 QMetaObject::activate qobject.cpp 3599 0x7ffff683655e
9 QMetaObject::activate qobject.cpp 3578 0x7ffff6836364
10 QQuickItem::widthChanged moc_qquickitem.cpp 1104 0x7ffff7a7ba49
11 QQuickItem::geometryChanged qquickitem.cpp 3533 0x7ffff7a6e9cd
12 QQuickItem::setSize qquickitem.cpp 6389 0x7ffff7a75f35
13 QQuickAnchorsPrivate::setItemSize qquickanchors.cpp 400 0x7ffff7a60d94
14 QQuickAnchorsPrivate::fillChanged qquickanchors.cpp 177 0x7ffff7a5fe0e
15 QQuickAnchorsPrivate::itemGeometryChanged qquickanchors.cpp 441 0x7ffff7a6106f
16 QQuickItem::geometryChanged qquickitem.cpp 3523 0x7ffff7a6e96c
17 QQuickItem::setWidth qquickitem.cpp 6091 0x7ffff7a74c1d
18 QQuickItem::qt_static_metacall moc_qquickitem.cpp 874 0x7ffff7a7b0dc
19 QQuickItem::qt_metacall moc_qquickitem.cpp 946 0x7ffff7a7b4d8
20 QQuickRectangle::qt_metacall moc_qquickrectangle_p.cpp 610 0x7ffff7c189c2
21 QMetaObject::metacall qmetaobject.cpp 296 0x7ffff680118b
22 QQmlPropertyPrivate::writeBinding qqmlproperty.cpp 1512 0x7ffff6e33ec3
23 QQmlBinding::update qqmlbinding.cpp 199 0x7ffff6eb992a
24 QQmlBinding::update qqmlbinding_p.h 97 0x7ffff6eba354
25 QQmlBinding::expressionChanged qqmlbinding.cpp 260 0x7ffff6eb9e68
26 QQmlJavaScriptExpressionGuard_callback qqmljavascriptexpression.cpp 361 0x7ffff6eb223e
27 QQmlNotifier::emitNotify qqmlnotifier.cpp 94 0x7ffff6e9087a
28 QQmlData::signalEmitted qqmlengine.cpp 763 0x7ffff6e19a45
29 QMetaObject::activate qobject.cpp 3599 0x7ffff683655e
30 QMetaObject::activate qobject.cpp 3578 0x7ffff6836364
31 QQuickItem::widthChanged moc_qquickitem.cpp 1104 0x7ffff7a7ba49
32 QQuickItem::geometryChanged qquickitem.cpp 3533 0x7ffff7a6e9cd
33 QQuickItem::setSize qquickitem.cpp 6389 0x7ffff7a75f35
34 QQuickAnchorsPrivate::setItemSize qquickanchors.cpp 400 0x7ffff7a60d94
35 QQuickAnchorsPrivate::fillChanged qquickanchors.cpp 177 0x7ffff7a5fe0e
36 QQuickAnchorsPrivate::update qquickanchors.cpp 431 0x7ffff7a60fc6
37 QQuickAnchorsPrivate::updateOnComplete qquickanchors.cpp 425 0x7ffff7a60f93
38 QQuickItem::componentComplete qquickitem.cpp 4593 0x7ffff7a70944
39 QQmlObjectCreator::finalize qqmlobjectcreator.cpp 1207 0x7ffff6ecab66
40 QQmlComponentPrivate::complete qqmlcomponent.cpp 928 0x7ffff6e38609
41 QQmlComponentPrivate::completeCreate qqmlcomponent.cpp 964 0x7ffff6e386ee
42 QQmlComponent::completeCreate qqmlcomponent.cpp 957 0x7ffff6e386a0
43 QQmlComponent::create qqmlcomponent.cpp 791 0x7ffff6e37edd
44 QQuickView::continueExecute qquickview.cpp 476 0x7ffff7b720d4
45 QQuickViewPrivate::execute qquickview.cpp 124 0x7ffff7b7101f
46 QQuickView::setSource qquickview.cpp 253 0x7ffff7b71426
47 main main.cpp 24 0x4033e4
In der Backtrace, kann man sehen, dass die anchors.fill
Anker für das untergeordnete Element berechnet wird, wenn das Laden der Datei (Rahmen 35, 36). Das bewirkt, dass sich die Breite des untergeordneten Elements ändert (Frame 31), was eine Bindungsaktualisierung (Frame 25) für eine Bindung an die "width" -Eigenschaft (Frame 17) des übergeordneten Elements verursacht. Dies zwingt wiederum eine Neuberechnung der Kindanker (Rahmen 14), was die Breite des Kindes (Rahmen 10) ändert, wodurch eine Bindung aktualisiert wird (Rahmen 4). Das ist die gleiche Bindung, die bereits in Rahmen 25 aktualisiert wurde, daher existiert eine Bindungsschleife. Man kann sehen, dass der Zeiger in Rahmen 25 und Rahmen 4 gleich sind, d. H. Die gleiche Bindung wird rekursiv aktualisiert.
Ich bin mir nicht sicher, aber IIRC qml Profiler können Sie verbindliche Anrufe sehen. Sie können auch eine Console Debug-Ausgabe in Eigenschaftenzuweisungen hinzufügen. Und du kannst deinen Code hier posten, damit wir dir helfen können :) –
Danke für deine Eingabe. Der QML-Profiler zeigt tatsächlich QML-Bindungsaufrufe an. Wie auch immer, afaics, zeigt es nicht, welcher zugrundeliegende C++ Code in der Schleife involviert ist. Ich habe (und hoffe immer noch) auf einige Protokolle gehofft, die z. "a bindet an b" "b bindet an c" "c bindet an eine" –
Nun, wenn es eine Option dafür gibt, weiß ich es nicht. Aber das mache ich manchmal, um Loops zu debuggen: 'height: {console.debug (" binding height "); return parent.height; } '. Beachten Sie, dass dies keine Bindung selbst erzeugt, Sie müssen 'Qt.binding ...' verwenden http://doc.qt.io/qt-5/qtqml-syntax-propertybinding.html –