我有一個使用C++模型和QML可視化的Qt/QML應用程序。如何分析「綁定循環」
在運行時(啓動),我得到一個警告
QML項目:綁定的屬性「XYZ」檢測環路
我看到我的QML沒有明顯的循環。 我可以啓用更多調試來了解此循環的來源?其他建議?
我有一個使用C++模型和QML可視化的Qt/QML應用程序。如何分析「綁定循環」
在運行時(啓動),我得到一個警告
QML項目:綁定的屬性「XYZ」檢測環路
我看到我的QML沒有明顯的循環。 我可以啓用更多調試來了解此循環的來源?其他建議?
我通常通過在打印警告的Qt代碼中放置一個斷點來做到這一點。爲此,你需要有一個帶有調試符號的Qt。
在Qt源文件中搜索「Binding loop detected」給出QQmlAbstractBinding::printBindingLoopError()。放置斷點通常會導致回溯,從而清楚地瞭解情況。
更新:David Edmundson開發了一個小工具,在綁定循環上顯示僅QML回溯,參見his blog here。底下是這裏所描述的內容,只是它很好地自動化並且封裝在一個Python腳本中。
實施例:
Rectangle {
id: parent
width: child.width + 1
height: child.height + 1
Rectangle {
id: child
anchors.fill: parent
}
}
回溯:
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
在回溯,人們可以看到,加載文件(框35,36)當anchors.fill
錨爲子項被計算。這會導致子項目的寬度發生更改(第31幀),這會導致綁定更新(第25幀)在父項目的「寬度」屬性(第17幀)上進行綁定。這又強制重新計算改變孩子的寬度的框架(框架14)(框架10),其更新了框架(框架4)。這是與第25幀中已更新的綁定相同,因此存在綁定循環。可以看到,幀25和幀4中的this
指針是相同的,即遞歸地更新相同的綁定。
這看起來很有前途!你能指導我如何得到一個「帶調試符號的Qt」嗎?我應該自己編譯Qt嗎? –
如果您在Linux上,請安裝'* -dbg'軟件包。 – Velkan
我從源代碼編譯Qt,所以我只是將''-debug''標誌傳遞給''configure''。不知道預構建的軟件包。 –
我不確定,但是IIRC qml profiler讓你看到綁定調用。您也可以在屬性分配中添加控制檯調試輸出。你可以在這裏發佈你的代碼,所以我們可以幫助你:) – 2016-07-05 07:26:36
感謝您的意見。 QML分析器確實顯示QML綁定調用。但是,afaics並沒有顯示循環中涉及哪些底層C++代碼。我是(現在仍然)希望一些日誌表明例如。 「綁定到b」「b綁定到c」「c綁定到」 –
好吧,如果有這個選項,我不知道它。但是,我有時會這樣做來調試循環:'height:{console.debug(「binding height」);返回parent.height; }'。請注意,這不會創建綁定本身,你必須使用'Qt.binding ...'http://doc.qt.io/qt-5/qtqml-syntax-propertybinding.html – 2016-07-05 11:48:29