QQuickTreeView: add expandToIndex()
Add a function that lets you expand the tree recursively from an index in the model, and all the way up to the root. [ChangeLog][QtQuick] New function "expandToIndex()" has been added to TreeView. Change-Id: I063ef698e37f44730438e1638d3b7c1b4edaa0d0 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
This commit is contained in:
parent
7eeeb605f0
commit
c013439598
|
@ -175,6 +175,24 @@
|
|||
\sa collapseRecursively(), expand(), collapse(), isExpanded(), depth()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\qmlmethod QtQuick::TreeView::expandToIndex(QModelIndex index)
|
||||
\since 6.4
|
||||
|
||||
Expands the tree from the given model \a index, and recursively all the way up
|
||||
to the root. The result will be that the delegate item that represents \a index
|
||||
becomes visible in the view (unless it ends up outside the viewport). To
|
||||
ensure that the row ends up visible in the viewport, you can do:
|
||||
|
||||
\code
|
||||
expandToIndex(index)
|
||||
forceLayout()
|
||||
positionViewAtRow(rowAtIndex(index), Qt.AlignVCenter)
|
||||
\endcode
|
||||
|
||||
\sa expand(), expandRecursively()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\qmlmethod QtQuick::TreeView::collapse(row)
|
||||
|
||||
|
@ -302,6 +320,8 @@
|
|||
\a row and \a depth will be equal to the arguments given to the call
|
||||
that caused the expansion to happen (\l expand() or \l expandRecursively()).
|
||||
In case of \l expand(), \a depth will always be \c 1.
|
||||
In case of \l expandToIndex(), \a depth will be the depth of the
|
||||
target index.
|
||||
|
||||
\note when a row is expanded recursively, the expanded signal will
|
||||
only be emitted for that one row, and not for its descendants.
|
||||
|
@ -519,6 +539,55 @@ void QQuickTreeView::expandRecursively(int row, int depth)
|
|||
emit expanded(row, depth);
|
||||
}
|
||||
|
||||
void QQuickTreeView::expandToIndex(const QModelIndex &index)
|
||||
{
|
||||
Q_D(QQuickTreeView);
|
||||
|
||||
if (!index.isValid()) {
|
||||
qmlWarning(this) << "index is not valid: " << index;
|
||||
return;
|
||||
}
|
||||
|
||||
if (index.model() != d->m_treeModelToTableModel.model()) {
|
||||
qmlWarning(this) << "index doesn't belong to correct model: " << index;
|
||||
return;
|
||||
}
|
||||
|
||||
if (rowAtIndex(index) != -1) {
|
||||
// index is already visible
|
||||
return;
|
||||
}
|
||||
|
||||
int depth = 1;
|
||||
QModelIndex parent = index.parent();
|
||||
int row = rowAtIndex(parent);
|
||||
|
||||
while (parent.isValid()) {
|
||||
if (row != -1) {
|
||||
// The node is already visible, since it maps to a row in the table!
|
||||
d->m_treeModelToTableModel.expandRow(row);
|
||||
|
||||
// Update the state of the already existing delegate item
|
||||
for (int c = leftColumn(); c <= rightColumn(); ++c) {
|
||||
const QPoint treeNodeCell(c, row);
|
||||
if (const auto item = itemAtCell(treeNodeCell))
|
||||
d->setRequiredProperty("expanded", true, d->modelIndexAtCell(treeNodeCell), item, false);
|
||||
}
|
||||
|
||||
// When we hit a node that is visible, we know that all other nodes
|
||||
// up to the parent have to be visible as well, so we can stop.
|
||||
break;
|
||||
} else {
|
||||
d->m_treeModelToTableModel.expand(parent);
|
||||
parent = parent.parent();
|
||||
row = rowAtIndex(parent);
|
||||
depth++;
|
||||
}
|
||||
}
|
||||
|
||||
emit expanded(row, depth);
|
||||
}
|
||||
|
||||
void QQuickTreeView::collapse(int row)
|
||||
{
|
||||
Q_D(QQuickTreeView);
|
||||
|
|
|
@ -77,6 +77,7 @@ public:
|
|||
|
||||
Q_REVISION(6, 4) Q_INVOKABLE void expandRecursively(int row = -1, int depth = -1);
|
||||
Q_REVISION(6, 4) Q_INVOKABLE void collapseRecursively(int row = -1);
|
||||
Q_REVISION(6, 4) Q_INVOKABLE void expandToIndex(const QModelIndex &index);
|
||||
|
||||
Q_INVOKABLE QModelIndex modelIndex(int row, int column) const;
|
||||
Q_INVOKABLE QModelIndex modelIndex(const QPoint &cell) const;
|
||||
|
|
|
@ -103,6 +103,7 @@ private slots:
|
|||
void collapseRecursivelyRoot();
|
||||
void collapseRecursivelyChild();
|
||||
void collapseRecursivelyWholeTree();
|
||||
void expandToIndex();
|
||||
void requiredPropertiesRoot();
|
||||
void requiredPropertiesChildren();
|
||||
void emptyModel();
|
||||
|
@ -692,6 +693,45 @@ void tst_qquicktreeview::collapseRecursivelyWholeTree()
|
|||
QCOMPARE(treeView->rows(), 1); // root
|
||||
}
|
||||
|
||||
void tst_qquicktreeview::expandToIndex()
|
||||
{
|
||||
// Check that expandToIndex(index) expands the tree so
|
||||
// that index becomes visible in the view
|
||||
LOAD_TREEVIEW("normaltreeview.qml");
|
||||
QSignalSpy spy(treeView, SIGNAL(expanded(int, int)));
|
||||
|
||||
const QModelIndex root = model->index(0, 0);
|
||||
const QModelIndex child1 = model->index(3, 0, root);
|
||||
const QModelIndex child2 = model->index(3, 0, child1);
|
||||
|
||||
QVERIFY(model->hasChildren(root));
|
||||
QVERIFY(model->hasChildren(child1));
|
||||
QVERIFY(model->hasChildren(child2));
|
||||
|
||||
QVERIFY(!treeView->isExpanded(treeView->rowAtIndex(root)));
|
||||
QVERIFY(!treeView->isExpanded(treeView->rowAtIndex(child1)));
|
||||
QVERIFY(!treeView->isExpanded(treeView->rowAtIndex(child2)));
|
||||
|
||||
const QModelIndex childToExpand = model->index(1, 0, child2);
|
||||
treeView->expandToIndex(childToExpand);
|
||||
|
||||
QVERIFY(treeView->isExpanded(treeView->rowAtIndex(root)));
|
||||
QVERIFY(treeView->isExpanded(treeView->rowAtIndex(child1)));
|
||||
QVERIFY(treeView->isExpanded(treeView->rowAtIndex(child2)));
|
||||
|
||||
QCOMPARE(spy.count(), 1);
|
||||
auto signalArgs = spy.takeFirst();
|
||||
QVERIFY(signalArgs.at(0).toInt() == 0);
|
||||
QVERIFY(signalArgs.at(1).toInt() == 3);
|
||||
|
||||
WAIT_UNTIL_POLISHED;
|
||||
|
||||
// The view should now have 13 rows:
|
||||
// root + 3 expanded nodes that each have 4 children
|
||||
QCOMPARE(treeView->rows(), 13);
|
||||
}
|
||||
|
||||
|
||||
QTEST_MAIN(tst_qquicktreeview)
|
||||
|
||||
#include "tst_qquicktreeview.moc"
|
||||
|
|
|
@ -48,6 +48,7 @@ ApplicationWindow {
|
|||
visible: true
|
||||
|
||||
property alias treeView: treeView
|
||||
property var selectedIndex: undefined
|
||||
|
||||
UICallback { id: callback }
|
||||
|
||||
|
@ -92,6 +93,16 @@ ApplicationWindow {
|
|||
treeView.model.removeRows(index.row, 1, index.parent);
|
||||
}
|
||||
}
|
||||
Button {
|
||||
text: "Expand to"
|
||||
enabled: selectedIndex != undefined
|
||||
onClicked: {
|
||||
treeView.expandToIndex(selectedIndex);
|
||||
treeView.forceLayout()
|
||||
let row = treeView.rowAtIndex(selectedIndex)
|
||||
treeView.positionViewAtRow(row, Qt.AlignVCenter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TreeView {
|
||||
|
@ -126,6 +137,16 @@ ApplicationWindow {
|
|||
treeView.expandRecursively(row)
|
||||
}
|
||||
}
|
||||
TapHandler {
|
||||
acceptedModifiers: Qt.ShiftModifier
|
||||
onTapped: selectedIndex = treeView.modelIndex(row, 0)
|
||||
}
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
border.color: "red"
|
||||
border.width: 1
|
||||
visible: treeView.modelIndex(row, column) === selectedIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue