我在模型/视图编程中尝试了一个例子。
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。
答案 0 :(得分:3)
QFileSystemModel使用延迟和延迟加载。您需要监视其信号,这些信号将不断发出,直到整个目录都已加载。
特别是,文档说
与QDirModel不同,QFileSystemModel使用单独的线程来填充自身,因此在查询文件系统时不会导致主线程挂起。调用rowCount()将返回0,直到模型填充目录。
在您的情况下,您可以运行本地QEventLoop并将模型的相应信号(directoryLoaded)与事件循环的quit()槽连接以等待填充。我不确定canFetchMore和fetchMore是否可用于此场景以及阻止等待群体(当用户在无限列表中向下滚动时,其主要用途是延迟加载,例如facebook pinwall流)。值得尝试,至少。
@Kuba正确地注意到本地事件循环本身并不需要。如果你能负担得起你创建QFileSystemModel
的上下文(例如将它存储为指针成员),并作为普通成员函数在插槽上作用。
答案 1 :(得分:0)
使用的原则是:
directoryLoaded
信号连接到插槽。模型加载根路径后,将发送信号。model.canFetchMore
和model.fetchMore
与感兴趣的文件夹的索引一起使用并立即返回来完成(或者您可以尝试使用已经准备好的文件夹条目,但是此替代方法需要管理文件夹的进度模型准备就绪)。model.fetchMore
之后,测试canFetchMore
将返回False
,这意味着您感兴趣的文件夹已完全加载并且{{1} }现在将返回正确的值。如果您对另一个文件夹感兴趣,请再次将model.rowCount
和model.canFetchMore
与新文件夹的索引一起使用。除了使用model.fetchMore
,您还可以将目标文件夹的路径与传递到插槽的参数进行比较。此字符串表示信号发送的路径。
您表示您正在使用C ++,但我没有使用该语言的代码,但是以下Python中的代码可以轻松翻译(model.canFetchMore
= self
,缩进线是等效的划到一个方括号中来分隔一个块)
this