What is wrong with this Qt code?

2019-09-20 06:10发布

问题:

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();
}

回答1:

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.



回答2:

You must create a new item for each row. Move

QListWidgetItem *newItem = new QListWidgetItem;

into the for loop.