Qt 学习之路 2(44):QFileSystemModel
Qt 学习之路 2(44):QFileSystemModel
上一章我们详细了解了QStringListModel。本章我们将再来介绍另外一个内置模型:QFileSystemModel。看起来,QFileSystemModel比QStringListModel要复杂得多;事实也是如此。但是,虽然功能强大,QFileSystemModel的使用还是简单的。
让我们从 Qt 内置的模型说起。实际上,Qt 内置了两种模型:QStandardItemModel和QFileSystemModel。QStandardItemModel是一种多用途的模型,能够让列表、表格、树等视图显示不同的数据结构。这种模型会将数据保存起来。试想一下,列表和表格所要求的数据结构肯定是不一样的:前者是一维的,后者是二维的。因此,模型需要保存有实际数据,当视图是列表时,以一维的形式提供数据;当视图是表格时,以二维的形式提供数据。QFileSystemModel则是另外一种方式。它的作用是维护一个目录的信息。因此,它不需要保存数据本身,而是保存这些在本地文件系统中的实际数据的一个索引。我们可以利用QFileSystemModel显示文件系统的信息、甚至通过模型来修改文件系统。
QTreeView是最适合应用QFileSystemModel的视图。下面我们看一段代码:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
FileSystemWidget::FileSystemWidget(QWidget *parent) :
QWidget(parent)
{
model = new QFileSystemModel;
model->setRootPath(QDir::currentPath());
treeView = new QTreeView(this);
treeView->setModel(model);
treeView->setRootIndex(model->index(QDir::currentPath()));
QPushButton *mkdirButton = new QPushButton(tr("Make Directory..."), this);
QPushButton *rmButton = new QPushButton(tr("Remove"), this);
QHBoxLayout *buttonLayout = new QHBoxLayout;
buttonLayout->addWidget(mkdirButton);
buttonLayout->addWidget(rmButton);
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(treeView);
layout->addLayout(buttonLayout);
setLayout(layout);
setWindowTitle("File System Model");
connect(mkdirButton, SIGNAL(clicked()),
this, SLOT(mkdir()));
connect(rmButton, SIGNAL(clicked()),
this, SLOT(rm()));
}
|
构造函数很简单,我们首先创建了QFileSystemModel实例,然后将其作为一个QTreeView的模型。注意我们将QFileSystemModel的根目录路径设置为当前目录。剩下来的都很简单,我们添加了按钮之类,这些都不再赘述。对于 treeView 视图,我们使用了setRootIndex()对模型进行过滤。我们可以尝试一下,去掉这一句的话,我们的程序会显示整个文件系统的目录;而这一句的作用是,从模型中找到 QDir::currentPath()所对应的索引,然后显示这一位置。也就是说,这一语句的作用实际是设置显示哪个目录。我们会在后面的章节中详细讨论index()函数。
现在,我们可以运行以下程序看看界面:

虽然我们基本一行代码都没写(有关文件系统的代码都没有写),但是从运行截图可以看出,QFileSystemModel完全将所能想到的东西——名称、大小、类型、修改时间等全部显示出来,可见其强大之处。
下面是mkdir()槽函数:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
void FileSystemWidget::mkdir()
{
QModelIndex index = treeView->currentIndex();
if (!index.isValid()) {
return;
}
QString dirName = QInputDialog::getText(this,
tr("Create Directory"),
tr("Directory name"));
if (!dirName.isEmpty()) {
if (!model->mkdir(index, dirName).isValid()) {
QMessageBox::information(this,
tr("Create Directory"),
tr("Failed to create the directory"));
}
}
}
|
正如代码所示,首先我们获取选择的目录。后面这个isValid()判断很重要,因为默认情况下是没有目录被选择的,此时路径是非法的,为了避免程序出现异常,必须要有这一步判断。然后弹出对话框询问新的文件夹名字,如果创建失败会有提示,否则就是创建成功。这时候你会发现,硬盘的实际位置的确创建了新的文件夹。
下面则是rm()槽函数:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
void FileSystemWidget::rm()
{
QModelIndex index = treeView->currentIndex();
if (!index.isValid()) {
return;
}
bool ok;
if (model->fileInfo(index).isDir()) {
ok = model->rmdir(index);
} else {
ok = model->remove(index);
}
if (!ok) {
QMessageBox::information(this,
tr("Remove"),
tr("Failed to remove %1").arg(model->fileName(index)));
}
}
|
这里同样需要先检测路径是否合法。另外需要注意的是,目录和文件的删除不是一个函数,需要调用isDir()函数检测。这一步在代码中有很清楚的描述,这里就不再赘述了。
实际上,我们这里不需要十分担心QFileSystemModel的性能问题,因为它会启动自己的线程进行文件夹扫描,不会发生因扫描文件夹而导致的主线程阻塞的现象。另外需要注意的是,QFileSystemModel会对模型的结果进行缓存,如果你要立即刷新结果,需要通知QFileSystemWatcher类。
如果仔细查看就会发现,我们的视图不能排序不能点击列头。为此,我们可以使用下面代码:
|
1
2
3
4
5
6
7
8
|
treeView->header()->setStretchLastSection(true);
treeView->header()->setSortIndicator(0, Qt::AscendingOrder);
treeView->header()->setSortIndicatorShown(true);
#if QT_VERSION >= 0x050000
treeView->header()->setSectionsClickable(true);
#else
treeView->header()->setClickable(true);
#endif
|
这是 Qt 中视图类常用的一种技术:如果我们要修改有关列头、行头之类的位置,我们需要从视图类获取到列头对象,然后对其进行设置。正如代码中所显示的那样。注意上面代码片段的最后一部分,我们使用一个条件判断来确定 Qt4 与 Qt5 的不同。
现在我们简单介绍了有关两个常用的模型类:QStringListModel 和 QFileSystemModel。下一章,我们将在此基础上详细介绍模型的相关细节。
Qt 学习之路 2(44):QFileSystemModel的更多相关文章
- Qt 学习之路 2(71):线程简介
Qt 学习之路 2(71):线程简介 豆子 2013年11月18日 Qt 学习之路 2 30条评论 前面我们讨论了有关进程以及进程间通讯的相关问题,现在我们开始讨论线程.事实上,现代的程序中,使用线程 ...
- Qt 学习之路 2(67):访问网络(3)
Qt 学习之路 2(67):访问网络(3) 豆子 2013年11月5日 Qt 学习之路 2 16条评论 上一章我们了解了如何使用我们设计的NetWorker类实现我们所需要的网络操作.本章我们将继续完 ...
- Qt 学习之路 2(66):访问网络(2)
Home / Qt 学习之路 2 / Qt 学习之路 2(66):访问网络(2) Qt 学习之路 2(66):访问网络(2) 豆子 2013年10月31日 Qt 学习之路 2 27条评论 上一 ...
- Qt 学习之路 2(53):自定义拖放数据
Qt 学习之路 2(53):自定义拖放数据 豆子 2013年5月26日 Qt 学习之路 2 13条评论上一章中,我们的例子使用系统提供的拖放对象QMimeData进行拖放数据的存储.比如使用QM ...
- Qt 学习之路 2(51):布尔表达式树模型
Qt 学习之路 2(51):布尔表达式树模型 豆子 2013年5月15日 Qt 学习之路 2 17条评论 本章将会是自定义模型的最后一部分.原本打算结束这部分内容,不过实在不忍心放弃这个示例.来自于 ...
- Qt 学习之路 2(48):QSortFilterProxyModel
Qt 学习之路 2(48):QSortFilterProxyModel 豆子 2013年4月11日 Qt 学习之路 2 6条评论 从本章开始,我们将逐步了解有关自定义模型的相关内容.尽管前面我们曾经介 ...
- Qt 学习之路 2(46):视图和委托
Home / Qt 学习之路 2 / Qt 学习之路 2(46):视图和委托 Qt 学习之路 2(46):视图和委托 豆子 2013年3月11日 Qt 学习之路 2 63条评论 前面我们介绍了 ...
- Qt 学习之路 2(45):模型
Home / Qt 学习之路 2 / Qt 学习之路 2(45):模型 Qt 学习之路 2(45):模型 豆子 2013年2月26日 Qt 学习之路 2 23条评论 在前面两章的基础之上,我们 ...
- Qt 学习之路 2(41):model/view 架构
Qt 学习之路 2(41):model/view 架构 豆子 2013年1月23日 Qt 学习之路 2 50条评论 有时,我们的系统需要显示大量数据,比如从数据库中读取数据,以自己的方式显示在自己的应 ...
随机推荐
- SQL语句 表字段的操作 添加,删除,修改表的字段
alter table 表名 drop constraint 约束名字 //删除字段的原有约束 alter table 表名 add constraint 约束名字 DEFAULT 默认值 for ...
- Tornado之抽屉实战(3)--注册
知识点应用:标签绑定事件,jQuery获取用户值-->AJAX发送数据-->后台路由系统-->业务逻辑处理-->ORM数据操作-->write返回-->AJAX回调 ...
- 【转发】徐汉彬:Web系统大规模并发——电商秒杀与抢购
徐汉彬:Web系统大规模并发——电商秒杀与抢购 发表于2014-12-02 09:30| 73110次阅读| 来源CSDN| 114 条评论| 作者徐汉彬 问底徐汉彬大数据 摘要:电商的秒杀和抢购,从 ...
- mfs教程(一)
对于mfs文件系统也用了半年了,确实不错,最近又翻译了作者的三篇文章,再此一同发上,希望对大家有所帮助.不足之处还请指出,以便完善,谢谢! 感谢网友nonamexz做了精美的pdf文档 MFS文件系统 ...
- maven安装错误履历
1\:maven cannot find entry:"/src/main/java" 先删除source下的文件夹 再新建文件夹
- SpringBoot:阿里数据源配置、JPA显示sql语句、格式化JPA查询的sql语句
1 数据源和JPA配置 1.1 显示sql配置和格式化sql配置 者两个配置都是属于hibernate的配置,但是springdatajpa给我们简化了:所有hibernate的配置都在jpa下面的p ...
- SpringAOP01 利用AOP实现权限验证、利用权限验证服务实现权限验证
1 编程范式 1.1 面向过程 1.2 面向对象 1.3 面向切面编程 1.4 函数式编程 1.5 事件驱动编程 2 什么是面向切面编程 2.1 是一种编程范式,而不是一种编程语言 2.2 解决一些特 ...
- 【项目运行异常】BeanFactory not initialized or already closed - call 'refresh' before accessing beans via the ApplicationContext
java.lang.IllegalStateException: LifecycleProcessor not initialized - call 'refresh' before invoking ...
- 12-scanf("%*s")与printf("%*s")
在scanf里用*修饰符,是起到过滤读入的作用.比如一个有三列数值的数据,我只想得到第2列数值,可以在循环里用scanf(“%*d%d%*d”,a[i])来读入第i行的第2个数值到a[i]. ...
- html页面源代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...