-1

I was reading MVC tutorial and wanted to try out the code, but for some reason (which I'm not able to figure out) it is not working.

This code is suppose to show contents of current directory in QListWidget.

#include <QApplication>
#include <QFileSystemModel>
#include <QModelIndex>
#include <QListWidget>
#include <QListView>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QFileSystemModel *model = new QFileSystemModel;
    QString dir = QDir::currentPath();
    model->setRootPath(dir);
    QModelIndex parentIndex = model->index(dir);
    int numRows = model->rowCount(parentIndex);
    QListWidget *list = new QListWidget;
    QListWidgetItem *newItem = new QListWidgetItem;

    for(int row = 0; row < numRows; ++row) {
        QModelIndex index = model->index(row, 0, parentIndex);
        QString text = model->data(index, Qt::DisplayRole).toString();
        newItem->setText(text);
        list->insertItem(row, newItem);
    }

    list->show();
    return a.exec();
}
nik
  • 8,387
  • 13
  • 36
  • 44
  • 8
    "it's not working" is not very descriptive of the problem. If you want help, please let people know what you need help with. Does it compile? What does it do? How do you know "it's not working"? What have you tried? Help *us* help *you*. – KevenK Dec 08 '10 at 20:20
  • I could probably tell you what the problem is, but you might get offended. – Edward Strange Dec 08 '10 at 20:41
  • 1
    If you have nothing useful to add, please don't increase the length of the page. And I agree, I should have been more descriptive. – nik Dec 08 '10 at 23:05

2 Answers2

4

There are 2 problems.

The first described by Frank Osterfeld's answer. Move:

QListWidgetItem *newItem = new QListWidgetItem;

into your loop.

The second has to do with QFileSystemModel's threading model. from the docs for QFileSystemModel:

Unlike the QDirModel, QFileSystemModel uses a separate thread to populate itself so it will not cause the main thread to hang as the file system is being queried. Calls to rowCount() will return 0 until the model populates a directory.

and

Note: QFileSystemModel requires an instance of a GUI application.

I don't think QFileSystemModel() will work properly until after the Qt event loop is running (which is started by a.exec() in your example).

In your case, model->rowCount(parentIndex) returns 0, even though there are items in the directory (at least that's what it's doing on my test).

Replacing QFileSystemModel with QDirModel (and removing the model->setRootPath(dir) call, which QDirModel` doesn't support) populates the list.

Community
  • 1
  • 1
Michael Burr
  • 333,147
  • 50
  • 533
  • 760
  • perfect, now when I use QListView and QFileSystemModel in the code above, things work fine. Nos is it because the QListView will update itself once model has updated itself? – nik Dec 08 '10 at 22:58
  • I'm a Qt novice myself at this point (and I'm not really a GUI programmer in general). I can't help much with details about the Qt model/view architecture, but your conclusion about QListView/QFileSystemModel seems reasonable. – Michael Burr Dec 08 '10 at 23:26
1

You must create a new item for each row. Move

QListWidgetItem *newItem = new QListWidgetItem;

into the for loop.

Frank Osterfeld
  • 24,815
  • 5
  • 58
  • 70