参考:
QDirModel_w3cschool
https://www.w3cschool.cn/learnroadqt/emq31j4k.html
C++ GUI Programming with Qt 4, Second Edition
本地环境:
win10专业版,64位,Qt 5.12
上一篇:
qt5-入门-ModelView架构1-CSDN博客
https://blog.csdn.net/pxy7896/article/details/136027518
QDirModel&QFileSystemModel
效果
实现
注意:
- QDirModel 在最新版 Qt 中已经不建议使用了。文档中说使用 QFileSystemModel 代替
- 与QDirModel 不同的是,QFileSystemModel会启动自己的线程进行文件夹的扫描,因此不会发生因扫描文件夹而导致的主线程阻塞的现象。
头文件:
#ifndef DMTREEVIEW_H
#define DMTREEVIEW_H
#include <QDirModel>
#include <QTreeView>
#include <QFileSystemModel>
class MyTreeView : public QWidget
{
Q_OBJECT
public:
MyTreeView();
private:
//QDirModel *model;
QFileSystemModel *model;
QTreeView *treeView;
private slots:
void mkdir();
void rm();
};
#endif // DMTREEVIEW_H
源文件里大部分代码是QDirModel用的,QFileSystemModel用的会注明。
源文件:
#include "dmtreeview.h"
#include <QTreeView>
#include <QHeaderView>
#include <QHBoxLayout>
#include <QPushButton>
#include <QInputDialog>
#include <QMessageBox>
MyTreeView::MyTreeView() {
//model = new QDirModel;
model = new QFileSystemModel;
model->setReadOnly(false);
// QDirModel
// 排序依据:文件夹优先、忽略大小写、名字
//model->setSorting(QDir::DirsFirst | QDir::IgnoreCase | QDir::Name);
// QFileSystemModel
model->setRootPath(""); // 需要设置根目录,QDirModel自动使用根目录
// 似乎默认是文件夹优先,按名称升序了,这样设置就ok
model->sort(0, Qt::AscendingOrder);
// 似乎不需要观察或者手动刷新啊?
//QFileSystemWatcher watcher;
//watcher.addPath(model->rootPath());
treeView = new QTreeView;
treeView->setModel(model);
// 当 QTreeView 的宽度大于所有列宽之和时,最后一列的宽度自动扩展
// 以充满最后的边界;否则就让最后一列的宽度保持原始大小
treeView->header()->setStretchLastSection(true);
// 因为前面model设置了按名字排序,所以用0
treeView->header()->setSortIndicator(0, Qt::AscendingOrder);
// 显示排序按钮
treeView->header()->setSortIndicatorShown(true);
treeView->header()->setSectionsClickable(true);
// 获取当前exe文件运行路径
QModelIndex index = model->index(QDir::currentPath());
treeView->expand(index);
treeView->scrollTo(index);
// 要求列头适应内容宽度,不折叠(...)
treeView->resizeColumnToContents(0);
// 两个按钮的布局
QHBoxLayout *btnLayout = new QHBoxLayout;
QPushButton *createBtn = new QPushButton(tr("Create Directory..."));
QPushButton *delBtn = new QPushButton(tr("Remove"));
btnLayout->addWidget(createBtn);
btnLayout->addWidget(delBtn);
// 总布局
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->addWidget(treeView);
mainLayout->addLayout(btnLayout);
this->setLayout(mainLayout);
connect(createBtn, SIGNAL(clicked()), this, SLOT(mkdir()));
connect(delBtn, SIGNAL(clicked()), this, SLOT(rm()));
}
void MyTreeView::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"));
}
}
}
void MyTreeView::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)));
}
}