QFileSystemModel rowCount无法按预期工作

时间:2015-11-05 12:31:39

标签: c++ qt rowcount qfilesystemmodel

我在模型/视图编程中尝试了一个例子。

http://doc.qt.io/qt-5/model-view-programming.html

为了演示如何使用模型索引从模型中检索数据,我们设置了一个没有视图的QFileSystemModel,并在窗口小部件中显示文件和目录的名称。虽然这没有显示使用模型的常规方法,但它演示了模型在处理模型索引时使用的约定。

我们按以下方式构建文件系统模型:

QFileSystemModel *model = new QFileSystemModel;
QModelIndex parentIndex = model->index(QDir::currentPath());
int numRows = model->rowCount(parentIndex);

在这种情况下,我们设置一个默认的QFileSystemModel,使用该模型提供的index()的特定实现获取父索引,并使用rowCount()函数计算模型中的行数。

这是我的代码:

QFileSystemModel* model = new QFileSystemModel;
QModelIndex parentIndex = model->index(QDir::currentPath());
qDebug() << QDir::currentPath();
// "/media/Local Data/Files/Programming/C++/build-DemostrateQModelIndex-Desktop_Qt_5_5_1_GCC_64bit-Debug"
qDebug() << "RowCount is " << model->rowCount(parentIndex);

但RowCount始终为0。

在&#34; build-DemostrateQModelIndex-Desktop_Qt_5_5_1_GCC_64bit-Debug&#34;文件夹,里面有文件和文件夹。我希望行数应该是里面的项目数。

我也尝试初始化QFileSystemModel;

QFileSystemModel* model = new QFileSystemModel;
model->setRootPath(QDir::rootPath());
QModelIndex parentIndex = model->index(QDir::currentPath());
qDebug() << "RowCount is " << model->rowCount(parentIndex);

RowCount仍为0。

更新1: 应用Johannes Schaub的建议。我在代码中添加了QEventLoop

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

    QFileSystemModel* model = new QFileSystemModel;
    model->setRootPath(QDir::rootPath());
    QModelIndex parentIndex = model->index(QDir::currentPath());
    qDebug() << QDir::currentPath();
    // "/media/Local Data/Files/Programming/C++/build-DemostrateQModelIndex-Desktop_Qt_5_5_1_GCC_64bit-Debug"
    qDebug() << "First RowCount Call is " << model->rowCount(parentIndex);

    QEventLoop loop;
    QObject::connect(model, &QFileSystemModel::directoryLoaded, &loop, &QEventLoop::quit);
    loop.exec();
    qDebug() << "RowCount Call after eventloop is  " << model->rowCount(parentIndex);

    return a.exec();
}

我的行数仍为0。

2 个答案:

答案 0 :(得分:3)

QFileSystemModel使用延迟和延迟加载。您需要监视其信号,这些信号将不断发出,直到整个目录都已加载。

特别是,文档说

  

与QDirModel不同,QFileSystemModel使用单独的线程来填充自身,因此在查询文件系统时不会导致主线程挂起。调用rowCount()将返回0,直到模型填充目录。

在您的情况下,您可以运行本地QEventLoop并将模型的相应信号(directoryLoaded)与事件循环的quit()槽连接以等待填充。我不确定canFetchMore和fetchMore是否可用于此场景以及阻止等待群体(当用户在无限列表中向下滚动时,其主要用途是延迟加载,例如facebook pinwall流)。值得尝试,至少。

@Kuba正确地注意到本地事件循环本身并不需要。如果你能负担得起你创建QFileSystemModel的上下文(例如将它存储为指针成员),并作为普通成员函数在插槽上作用。

答案 1 :(得分:0)

使用的原则是:

  • 创建模型并设置其根路径。在这一阶段,您可以假设模型仍然为空或仅加载了很少的数据。
  • 让模型在其单独的内部线程中加载数据。将directoryLoaded信号连接到插槽。模型加载根路径后,将发送信号。
  • 在插槽中,检查您感兴趣的文件夹是否已完全加载。起初不会。原因是使用惰性方法加载模型,可能只有根路径文件夹可以使用。
  • 如果文件夹尚未完全准备好,请模型加载它。这可以通过将model.canFetchMoremodel.fetchMore与感兴趣的文件夹的索引一起使用并立即返回来完成(或者您可以尝试使用已经准备好的文件夹条目,但是此替代方法需要管理文件夹的进度模型准备就绪)。
  • 插槽准备就绪时(可能在调用model.fetchMore之后,测试canFetchMore将返回False,这意味着您感兴趣的文件夹已完全加载并且{{1} }现在将返回正确的值。如果您对另一个文件夹感兴趣,请再次将model.rowCountmodel.canFetchMore与新文件夹的索引一起使用。

除了使用model.fetchMore,您还可以将目标文件夹的路径与传递到插槽的参数进行比较。此字符串表示信号发送的路径。


您表示您正在使用C ++,但我没有使用该语言的代码,但是以下Python中的代码可以轻松翻译(model.canFetchMore = self,缩进线是等效的划到一个方括号中来分隔一个块)


this