1

I am dealing with a Qt application in which I would like to retrieve the total number of navigatable rows in a Directory/Filesystem model-like tree. That means if a folder is expanded its count is added, if a folder is collapsed its count is not added. As a whole, I want to be able to retrieve the number of every row that is expanded and available. As far as I could see, there is not such an implementation easy to find online. Two solutions that did not work yet:

int MainWindow::countRowsOfIndex_treeview( const QModelIndex & index )
{
    int count = 0;
    const QAbstractItemModel* model = index.model();
    int rowCount = model->rowCount(index);
    count += rowCount;
    for( int r = 0; r < rowCount; ++r )
        count += countRowsOfIndex_treeview( model->index(r,0,index) );
    return count;
}

This is not even close to what I want to achieve as it does not consider the unexpanded folders.

So far, I have been dealing with the one-level row count using:

ui->treeView->model()->rowCount(ui->treeView->currentIndex().parent())

However, this does not count the unexpanded childs and so on. I hope my question is clear. Any help is appreciated. I'm willing to give any more information if requested. Thanks.

mozcelikors
  • 2,582
  • 8
  • 43
  • 77
  • I don't think you are on the right path. By definition the fact that a node is expanded or not is managed by the view, the model has no knowledge on that. So it should be better to look in the view API, for example this one and the others around bool QTreeView::isExpanded(const QModelIndex &index) const – sandwood May 16 '18 at 13:53

1 Answers1

1

You can check for your view if every index is expanded or not. Then it's only a question of traversing the model.

Credit of Kuba Order : How to loop over QAbstractItemView indexes?

Based on his nice traversal function:

void iterate(const QModelIndex & index, const QAbstractItemModel * model,
             const std::function<void(const QModelIndex&, int)> & fun,
             int depth = 0)
{
    if (index.isValid())
        fun(index, depth);
    if (!model->hasChildren(index)) return;
    auto rows = model->rowCount(index);
    auto cols = model->columnCount(index);
    for (int i = 0; i < rows; ++i)
        for (int j = 0; j < cols; ++j)
            iterate(model->index(i, j, index), model, fun, depth+1);
}

, you can easily write your need :

int countExpandedNode(QTreeView * view) {
    int totalExpanded = 0;
    iterate(view->rootIndex(), view->model(), [&totalExpanded,view](const QModelIndex & idx, int depth){
        if (view->isExpanded(idx))
            totalExpanded++;
    });
    return totalExpanded;
}

calling code like that :

QTreeView view;
view.setModel(&model);
view.setWindowTitle(QObject::tr("Simple Tree Model"));

view.expandAll();
view.show();


qDebug() << "total expanded" << countExpandedNode(&view);

I've tested it quickly on the Qt TreeModel example, it seems to work.

sandwood
  • 2,038
  • 20
  • 38