オブジェクトのツリーを作成します。ツリーは非常に単純なロジックを使用して描画されます。
- 各オブジェクトは、それ自体の表現とその子 (およびその子など...) の表現と同じ大きさです。
- オブジェクトがその親の最初の子である場合、視覚的表現の下にインデントされて描画されます
- 次のすべてのオブジェクトは、前の兄弟の下に直接描画されます
ただし、この単純なアルゴリズムは、新しいオブジェクトを挿入するときに失敗する場合があります。例えば:
この場合、ノード 1 と 2 はノード 0 に正常に挿入され、ノード 0 の全高 (各ノードの左側にある黒い線) は、それ自身の UI とその両方の子の合計になります。
しかし、ノード 3 がノード 1 に挿入されると、レイアウトが壊れます。ノード 2 は押し下げられません。その結果、新しく挿入されたノードと重なり、黒い線が見えなくなります。
追加の更新サイクルがトリガーされると、ツリーは通常に戻るため、グリッチは一時的な「または同期」プロパティが原因である必要があります。追加の 1 回の更新で常にツリーが整頓されるとは限らないことに注意してください。挿入が行われる場所によっては、バグが整列を妨げないように「カスケード アウト」するために数回の更新サイクルが必要になる場合があります。
この不規則な動作の原因および/またはそれを修正する方法はありますか? コードがときどき壊れる原因は何ですか? また、最終的には機能するのに、正常に機能するために 1 回から複数回の更新が必要になるのはなぜですか?
編集:私は、そのレベルの最後のノードで終わっていないノードに挿入するときに、位置合わせがいつ壊れるかを特定して特定することができました。すべてのバインディングは、新しいノードが最後に「開いている」ノードに挿入されている限り、適切に伝播されます。たとえば、そのレベルには次のノードはありませんが、前のノードに挿入するとバインディングが壊れます。そのため、影響を受けるすべてのレベルでバグを段階的に排除するには、追加の更新サイクルが必要です。しかし、何が原因で、どのように修正するかはまだわかりません。発生した場合のみです。
編集: もう少し調査すると、新しい子が親アイテムに挿入され、その子が順序に基づいて再配置された後、childrenRect
親のプロパティはサイズの変更をすぐには反映しないようです。したがって、挿入されたオブジェクトの次の兄弟が配置されているとき、オブジェクトの高さには古い古い値が引き続き使用されますが、これは使用されないため、新しく挿入されたオブジェクトには影響しません。したがって、次の大きな問題は、アルゴリズムが適切なデータで期待どおりに機能するように、バインドが適切に行われるように修正する方法だと思いますか? タイマーを使用して操作を遅らせてみましたが、時間の問題ではなく、論理的な順序、たとえば、バグが発生した部門に等しいバグを排除するために現在必要な更新の数についてのようです。
編集:「解決する」方法を考えましたが...実際には、原因と回避方法はまだわかりませんが、修正されるまでツリー全体を更新するよりも少し「経済的な」解決策です親を下って、ルートに到達するまで現在のブランチのみを更新します。これにより多くの節約ができますが、少なくとも IMO ではバインディングが機能するはずなので、正しい値をすぐに取得することをお勧めします。
編集:注文コードは次のとおりです。
for (int i = 0; i < _children.size(); ++i) {
UI * ui = _children.at(i)->_ui;
if (ui) {
if (i) {
UI * prev = _children.at(i-1)->_ui;
ui->setX(prev->x());
ui->setY(prev->height() + prev->y());
} else {
ui->setX(Object::_helper->nodeSize());
ui->setY(_ui->childOffset());
}
}
}
QML の設定方法の例:
UI {
id: main
width: childrenRect.width
height: childrenRect.height
Item {
height: childrenRect.height
Rectangle {
width: Helper.nodeSize
height: Helper.nodeSize
color: "red"
Text {
anchors.centerIn: parent
text: main.id
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: {
if (mouse.button == Qt.RightButton)
Helper.gotoXY(main.absolutePosition())
else {
Helper.createObject(1, main)
Helper.updateRoot()
}
}
Rectangle {
height: main.height
width: 10
x: -10
color: "black"
}
}
}
}
}