2016-07-05 5 views
4

私はC++モデルとQMLビジュアライゼーションを備えたQt/QMLアプリケーションを持っています。実行時に"バインディングループ"を分析する方法

(起動)を、私は

QMLアイテム警告を受ける:バインディングプロパティの検出ループは「XYZ」

私はQMLに明らかなループを見ません。 このループの原因を理解するために、さらにデバッグを有効にすることはできますか?その他の提案?

+0

わかりませんが、IIRC qmlプロファイラを使用すると、バインディング呼び出しを確認できます。また、プロパティの割り当てにコンソールデバッグ出力を追加することもできます。そして、私たちがあなたを助けることができるようにここにあなたのコードを投稿することができます:) –

+0

あなたの入力をありがとう。 QMLプロファイラは実際にQMLバインディング呼び出しを示します。ただし、実際のC++コードがループに含まれているかどうかはわかりません。私は(そしてまだ)、例えばいくつかのログを期待していました。 "aはbにバインド" "bはcにバインド" "cは"にバインドする –

+0

これはオプションがあれば分かりません。しかし、これはループをデバッグするために時々行うことです: 'height:{console.debug(" binding height "); return parent.height; } '。これはバインディング自体を作成しないので、 'Qt.binding ...'を使う必要があります。http://doc.qt.io/qt-5/qtqml-syntax-propertybinding.html –

答えて

5

私は通常、警告を出力するQtコードにブレークポイントを設定します。そのためには、デバッグシンボル付きのQtが必要です。

Qtソースで「結合ループが検出されました」を検索すると、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)、親アイテムの「幅」プロパティ(フレーム17)上のバインディングのバインディングの更新(フレーム25)が発生します。その結果、子アンカー(フレーム14)の再計算が強制され、子の幅(フレーム10)が変更され、バインディング(フレーム4)が更新されます。これはフレーム25で既に更新されていたものと同じバインディングなので、バインディングループが存在します。フレーム25およびフレーム4のthisポインタが同じであること、すなわち同じバインディングが再帰的に更新されることが分かる。

+0

これは有望です! 「デバッグシンボル付きQt」を取得する方法を教えてください。 Qtを自分でコンパイルすべきですか? –

+0

Linuxの場合は、 '* -dbg'パッケージをインストールしてください。 – Velkan

+0

ソースからQtを自分でコンパイルするので、 '' -debug''フラグを '' configure''に渡すだけです。あらかじめビルドされたパッケージについては考えません。 –

関連する問題