qtqmodelindexqabstractitemview

How to loop over QAbstractItemView indexes?


I want to fire QAbstractItemView::doubleClicked slot programaticaly for an item that has specific text. I want to do this using QAbstractItemView class and not it's implementations if possible.

This task boils down to looping over items and comparing strings. But I cannot find any method that would give me all QModelIndexes. The only method that gives any QModelIndex without parameters is QAbstractItemView::rootIndex. But when I look into QModelIndex docs, I again cannot see a way to access it's children and siblings.

So how to access all QModelIndexes in QAbstractItemView?


Solution

  • The indexes are provided by the model, not by the view. The view provides the rootIndex() to indicate what node in the model it considers as root; it might be an invalid index. Otherwise it has nothing to do with the data. You have to traverse the model itself - you can get it from view->model().

    Here's a depth-first walk through a model:

    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 ((index.flags() & Qt::ItemNeverHasChildren) || !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);
    }
    

    The functor fun gets invoked for every item in the model, starting at root and going in depth-row-column order.

    E.g.

    void dumpData(QAbstractItemView * view) {
        iterate(view->rootIndex(), view->model(), [](const QModelIndex & idx, int depth){
            qDebug() << depth << ":" << idx.row() << "," << idx.column() << "=" << idx.data();
        });
    }