Aykhan Hagverdili
Aykhan Hagverdili

Reputation: 29985

QModelIndex as parent?

In Qt, QModelIndex is used to represent an index to my understanding. Officially:

This class is used as an index into item models derived from QAbstractItemModel. The index is used by item views, delegates, and selection models to locate an item in the model.

But I see it being used to represent a parent object. For instance, if I want to get an index in a QFileSystemModel object, I need a row, column and a parent:

QModelIndex QFileSystemModel::index(int row, int column, const QModelIndex &parent = QModelIndex()) const

I am trying to get a QModelIndex object, but to do that, I need another QModelIndex object? I am merely trying to iterate over the model. I don't have a separate parent object. How do I just create an index from row/column number? I don't understand the role of QModelIndex as a "parent". Shouldn't the model itself know what the parent object is? We passed a pointer to the constructor when creating the model.

Here's a bit of code showing the problem:

#include "MainWindow.hpp"
#include "ui_MainWindow.h"

#include <QFileSystemModel>
#include <QDebug>


MainWindow::MainWindow(QWidget *parent) :
  QMainWindow(parent),
  ui(new Ui::MainWindow)
{
  ui->setupUi(this);

  auto* model = new QFileSystemModel{ui->listView};
  ui->listView->setModel(model);
  ui->listView->setRootIndex(model->setRootPath("C:\\Program Files"));
  connect(ui->pushButton, &QPushButton::clicked, [this] {
    auto* model = static_cast<QFileSystemModel*>(ui->listView->model());
    int row_count = model->rowCount();
    for (int i = 0; i != row_count; ++i) {
      qDebug() << model->fileName(model->index(i, 0)) << '\n';
    }
  });
}

Here I have a QListView object (*listView) and a QFileSystemModel object (*model). I would like to iterate over the model and do something, like print the names of the files. The output is

C:

No matter which directory the rootpath is. I assume that is because I did't pass anything as the parent.

Upvotes: 0

Views: 948

Answers (1)

Toby Speight
Toby Speight

Reputation: 30960

You're just accessing the children of the root of the QFileSystemModel when you default the parent node to QModelIndex() in the call model->index(i, 0).

If you also want to list the children of those items, we'll want to iterate them, too:

#include <QApplication>
#include <QDebug>
#include <QFileSystemModel>

void list_files(const QFileSystemModel *model, QModelIndex ix = {},
                QString indent = {})
{
    auto const row_count = model->rowCount(ix);
    for (int i = 0;  i < row_count;  ++i) {
        auto const child = model->index(i, 0, ix);
        qDebug() << qPrintable(indent) << model->fileName(child);
        list_files(model, child, indent + " ");
    }
}

int main(int argc, char **argv)
{
    QApplication app(argc, argv);

    QFileSystemModel model;
    model.setRootPath(".");

    list_files(&model);
}

See how we pass the child index as the new parent when we recurse into list_files()?

Note that the model is likely incomplete at this stage, as it implements lazy reading - so don't expect to see all your files with this simple program.

Upvotes: 1

Related Questions