QT M/V架构开发实战:QFileSystemModel介绍

目录

    • @[TOC](目录)
  • 前言
  • 一、QFileSystemModel初步介绍
  • 二、基本功能
      • 1.创建
      • 2.基本属性与方法
  • 三、示例(简单的文件浏览器)
  • 四、性能注意事项

前言


本文主要介绍的是使用代码生成的情况下对控件的介绍,包括拥有的功能及能修改的样式,也会说明在qtdesiner拖拽控件生成和使用代码生成控件的区别(如果有的话,遇到了的会说),此版本不属于最终版本,以后遇到什么新奇的点会继续更新!本文基于QT官方的文档进行的编写,QT版本为qt 5.14.0,编写环境为Windows11。不得不说官方文档真是个好东西,有时候有些不会的上去一看就能有灵感解决了,可惜没有中文版本的。

一、QFileSystemModel初步介绍

QFileSystemModel是 Qt 提供的一个极其强大且实用的模型类,专门用于展示和操作本地文件系统。它抽象了文件系统的层次结构(目录树),并将其完美地适配到 Qt 的 Model-View 框架中,使得在 QTreeView、QListView或 QTableView中构建文件浏览器变得非常简单。

核心思想:​​
QFileSystemModel继承自 QAbstractItemModel(更具体地说,通常是 QDirModel的替代者,后者已废弃)。
将本地文件系统的目录结构映射为一个树状模型。
每个文件或目录对应模型中的一个项 (QModelIndex)。
提供了丰富的接口来获取文件属性(名称、路径、大小、类型、修改时间、权限、图标等)。
支持​​异步加载​​(默认),这意味着在后台线程中读取目录内容,避免阻塞 UI 线程,尤其是在处理大型目录或网络驱动器时体验更流畅。
自动监听文件系统的变化(通过 QFileSystemWatcher),并在文件或目录被添加、删除、重命名或修改时​​自动更新模型和视图​​。
读写操作(需谨慎):​​ 支持通过模型接口重命名、删除文件/目录(需要权限)。

二、基本功能

1.创建

#include <QFileSystemModel>QFileSystemModel *model = new QFileSystemModel(parent);

2.基本属性与方法

1)设置根路径
关键一步​​!告诉模型从哪个目录开始构建树状结构。视图(如 QTreeView)通常会自动展开并显示此根路径下的内容

// 设置根路径为当前用户的主目录
model->setRootPath(QDir::homePath());// 设置根路径为 C 盘 (Windows)
model->setRootPath("C:/");// 设置根路径为根目录 (Linux/macOS)
model->setRootPath("/");

2)连接视图

QTreeView *treeView = new QTreeView;
treeView->setModel(model); // 设置模型// 通常,你会将视图的根索引设置为模型的根路径索引
treeView->setRootIndex(model->index(model->rootPath()));

3)获取文件信息 (通过 QModelIndex或 QFileInfo)
使用 data()函数 (指定角色)

QModelIndex index = ...; // 例如 treeView->currentIndex() 或从选择模型获取// 文件/目录名 (DisplayRole)
QString name = model->data(index, Qt::DisplayRole).toString();// 完整路径 (FilePathRole - 这是 QFileSystemModel 特有的便捷角色)
QString fullPath = model->data(index, QFileSystemModel::FilePathRole).toString();
// 或者使用标准的 ToolTipRole 有时也会显示路径 (取决于视图)
QString toolTipPath = model->data(index, Qt::ToolTipRole).toString();// 文件大小 (SizeRole) - 目录通常返回 -1 或 0
qint64 size = model->data(index, QFileSystemModel::SizeRole).toLongLong();// 文件类型 (TypeRole) - 例如 "JPEG image", "Text Document", "Folder"
QString type = model->data(index, QFileSystemModel::TypeRole).toString();// 最后修改时间 (LastModifiedRole)
QDateTime lastModified = model->data(index, QFileSystemModel::LastModifiedRole).toDateTime();// 图标 (DecorationRole)
QIcon icon = model->data(index, Qt::DecorationRole).value<QIcon>();

使用 fileInfo()(更直接)

QFileInfo fileInfo = model->fileInfo(index);
QString name = fileInfo.fileName();
QString fullPath = fileInfo.absoluteFilePath();
qint64 size = fileInfo.size();
bool isDir = fileInfo.isDir();
bool isFile = fileInfo.isFile();
QDateTime lastModified = fileInfo.lastModified();
QFile::Permissions perms = fileInfo.permissions();
// ... 使用 QFileInfo 的所有丰富接口 ...

4)过滤显示的文件 (setFilter)
使用 QDir::Filters枚举组合来指定哪些文件和目录应该被显示。QDir::NoDotAndDotDot:通常建议加上,以排除 .(当前目录) 和 …(父目录) 项。

// 只显示目录 (不显示文件)
model->setFilter(QDir::AllDirs | QDir::NoDotAndDotDot);// 显示所有文件和目录 (默认)
model->setFilter(QDir::AllEntries | QDir::NoDotAndDotDot); // 通常排除 "." 和 ".."// 显示所有文件 (包括隐藏文件) 和目录
model->setFilter(QDir::AllEntries | QDir::Hidden | QDir::NoDotAndDotDot);// 只显示 .txt 和 .cpp 文件以及所有目录
model->setFilter(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot);
model->setNameFilters(QStringList() << "*.txt" << "*.cpp");
model->setNameFilterDisables(false); // true: 隐藏不匹配项; false: 显示但不匹配 (通常false)

5)排序 (sort)
视图的列顺序通常是:0=名称, 1=大小, 2=类型, 3=修改日期 (取决于 headerData实现)。

// 按名称排序 (默认)
treeView->setSortingEnabled(true); // 允许用户点击表头排序
treeView->sortByColumn(0, Qt::AscendingOrder); // 按第0列(名称)升序// 在代码中指定排序 (例如按大小降序)
model->sort(2, Qt::DescendingOrder); // 假设大小在第2列 (需要根据视图的列定义)

6)监听目录加载完成 (directoryLoaded信号)
由于加载是异步的,如果你需要在某个目录内容加载完成后执行操作(如展开、选择特定项),可以连接此信号。

connect(model, &QFileSystemModel::directoryLoaded,this, [this, model](const QString &path) {if (path == targetDirectoryPath) {// 找到并选中目标文件,或展开目录等QModelIndex targetIndex = model->index(targetFilePath);treeView->setCurrentIndex(targetIndex);treeView->scrollTo(targetIndex);}
});
model->setRootPath(targetDirectoryPath); // 或者调用 fetchMore(index) 触发加载

7)文件操作 (需谨慎!)
重命名 (setData)

QModelIndex oldIndex = ...;
bool success = model->setData(oldIndex, "NewFileName.txt", Qt::EditRole);
// 成功会触发 dataChanged 信号,视图更新
// 失败通常是因为权限不足或文件正在使用

创建目录 (mkdir)

QModelIndex parentDirIndex = ...; // 要在哪个目录下创建
QModelIndex newDirIndex = model->mkdir(parentDirIndex, "NewFolderName");
if (!newDirIndex.isValid()) {// 创建失败 (权限、重名等)
}

​删除 (remove)

QModelIndex indexToRemove = ...;
bool success = model->remove(indexToRemove);
if (!success) {// 删除失败 (权限、文件不存在等)
}

注意事项:​​ 这些操作会​​直接作用于真实文件系统​​!务必进行错误处理,并考虑提供用户确认(如删除确认对话框)。对于复杂的文件操作(复制、移动),通常建议使用 QFile、QDir或 QProcess调用系统命令,而不是依赖模型的 remove或 setData。

三、示例(简单的文件浏览器)

#include <QApplication>
#include <QSplitter>
#include <QTreeView>
#include <QListView>
#include <QFileSystemModel>int main(int argc, char *argv[]) {QApplication app(argc, argv);// 创建分割器窗口QSplitter *splitter = new QSplitter;// 创建模型QFileSystemModel *model = new QFileSystemModel;model->setRootPath(QDir::homePath()); // 设置根路径model->setFilter(QDir::AllEntries | QDir::NoDotAndDotDot); // 显示所有项// 创建树视图 (左侧 - 目录树)QTreeView *treeView = new QTreeView(splitter);treeView->setModel(model);treeView->setRootIndex(model->index(model->rootPath())); // 设置视图根索引treeView->setSortingEnabled(true); // 允许排序treeView->setAnimated(true); // 展开折叠动画treeView->setIndentation(20); // 缩进// 创建列表视图 (右侧 - 当前目录内容)QListView *listView = new QListView(splitter);listView->setModel(model);listView->setViewMode(QListView::IconMode); // 图标模式listView->setIconSize(QSize(64, 64)); // 图标大小// 连接树视图的点击信号,更新列表视图的根索引QObject::connect(treeView, &QTreeView::clicked,[model, listView](const QModelIndex &index) {if (model->isDir(index)) {listView->setRootIndex(index); // 点击目录,在列表视图中显示其内容}});// 初始设置列表视图显示根目录内容listView->setRootIndex(model->index(model->rootPath()));splitter->setWindowTitle("Simple File Browser");splitter->resize(800, 600);splitter->show();return app.exec();
}

四、性能注意事项

1、大型目录:​​ 加载包含成千上万文件的目录会消耗内存和时间。考虑:
使用 QDir手动加载部分项(但这失去了 MV 自动更新的优势)。
使用 QSortFilterProxyModel进行过滤,减少显示项**。
提示用户目录很大。

2、​​网络驱动器/慢速介质:​​ 异步加载尤为重要。directoryLoaded信号有助于知道何时加载完成。

​​3、文件监控:​​ QFileSystemWatcher可能会消耗资源(尤其是在 Windows 上监控大量文件)。如果不需要实时更新,可以考虑禁用(但 QFileSystemModel内部集成,没有直接禁用选项,可能需要自定义模型)。

本次分享就到这里了,如果有什么错误的话请指正,或者有什么疑问的,也可以在评论区一起探讨!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/96476.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/96476.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

视频生成迎来效率革命!字节提出视频生成稀疏注意力机制,计算量降20倍,速度升17.79倍!

论文链接&#xff1a;https://arxiv.org/pdf/2509.01085亮点直击BSA——一种可训练的双向动态稀疏注意力框架&#xff0c;该框架首次在视频扩散训练中对全注意力机制中的查询&#xff08;Query&#xff09;及键值对&#xff08;Key-Value&#xff09;进行正交稀疏化处理以加速训…

STM32HAL库_cubeMX

ADC简介STM32f103的是12位逼近型ADC代码连续非扫描模式&#xff08;1个通道&#xff09;1&#xff1a;校准ADC&#xff08;这个可要可不要&#xff09;2&#xff1a;ADC初始化3&#xff1a;配置ADC通道&#xff08;这个函数只有一个通道时就是可要可不要&#xff09;4&#xff…

【Qt】清空QDateTimeEdit

代码 ui->startDate->setSpecialValueText(" "); //这里是空格 ui->startDate->setMinimumDate(QDate(2024, 1, 1)); ui->startDate->setDate(QDate::fromString("2024-01-01", "yyyy-MM-dd"));原理 设置特殊值显示文本&#…

LiTS 2017 datasets

下载记录 论文地址&#xff1a;https://doi.org/10.1016/j.media.2022.102680 官方下载链接&#xff1a;https://competitions.codalab.org/competitions/17094 进入链接后&#xff0c;需要先注册才能拿到下载点击Train data下面的Mirro1&#xff0c;在google云盘会看到Trai…

kafka3.8集群搭建

kafka集群需要三台机器搭建&#xff0c;并使用内置zookeeperIP10.0.0.110.0.0.210.0.0.3安装jdk # ubuntu sudo apt install -y openjdk-8-jdk-headless # centos sudo yum install -y java-1.8.0-openjdk下载kafka wget https://archive.apache.org/dist/kafka/3.8.1/kafka_2…

从15kHz 到20MHz:为什么LTE带宽不能被子载波间隔整除?

从 15 kHz 到 20 MHz&#xff1a;为什么 LTE 带宽不能被子载波间隔整除&#xff1f; 1. 引言 在 LTE 系统中&#xff0c;子载波间隔被固定为 15 kHz&#xff0c;而系统带宽却被设计为 1.4、3、5、10、15、20 MHz 六个档位。乍一看&#xff0c;这些带宽似乎无法被 15 kHz 整除&a…

html css js网页制作成品——HTML+CSS娃娃店网页设计(4页)附源码

目录 一、👨‍🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML

【计算机网络 | 第15篇】动态主机配置协议

文章目录为何需要DHCP&#xff1f;手动配置的痛点&#x1f914;DHCP的基本工作模式&#x1f95d;DHCP的核心功能&#xff1a;IP地址的动态管理&#x1f95d;租用期的特点租用期的管理机制DHCP四步工作流程&#xff1a;从“发现”到“绑定”&#x1f426;‍&#x1f525;中继代理…

嵌入式系统内存分段核心内容详解

一、嵌入式内存分段整体规则&#xff08;按地址从低到高&#xff09;嵌入式系统内存按 “功能 属性” 划分为 6 个核心段&#xff0c;地址从低到高依次分布&#xff0c;各段职责与存储对象明确&#xff0c;具体规则如下表&#xff1a;地址范围段类型&#xff08;Segment&#…

开发避坑指南(45):Java Stream 求两个List的元素交集

需求 java 中如何用stream求两个List元素的交集&#xff1f; 代码实现 直接上代码 public class ListTest {public static void main(String[] args) {List<Integer> list1 new ArrayList<>();list1.add(1);list1.add(2);list1.add(3);List<Integer> list2 …

gitlab流水线与k8s集群的联通

gitlab流水线与k8s集群的连接&#xff0c;首先是通过gitlab-ci.yml文件中的命令&#xff0c;通过runner执行器实例运行对应的kubectl命令实现的。 那么runner执行器实例执行器如何执行kubectl命令&#xff0c;执行环境的配置&#xff0c;kubectl命令如何与k8s集群互认&#xff…

【Linux】常用命令速查表

Linux 常用命令速查表查看进程内存映射pmap -x <pid> # 查看进程的内存映射信息查看系统架构uname -m # 查看操作系统架构&#xff08;x86_64 / arm64 等&#xff09;磁盘与文件du -sh /home/* # 查看 /home 下每个用户目录的大小&#x…

Windows下编译SLEPc

本文记录在Windows下编译SLEPc的流程。 零、环境 操作系统Windows 11VS Code1.92.1MSYS2msys2-x86_64-20250830 一、安装依赖 1.1、依赖 首先&#xff0c;下载并安装MSYS2&#xff0c; 打开MSYS2 MINGW64控制台&#xff0c;运行以下命令安装依赖包&#xff0c; pacman -S …

运动生理实验室解决方案 人体生理实验整体解决方案

&#xff08;一&#xff09;、硬件参数 集成化折叠式无创型生理实验平台&#xff1a;1.1、 集成化设计:至少包含设备操作台、可收纳式交互实验桌、可收纳式检查床、生物信号 采集处理系统、计算机工作站集成于一体的高度集成设计&#xff1b;&#xff08;o561-6o623…

Axure RP 9 最新版安装包+安装步骤Win系统适用(附安装包)

Axure RP 9​ 是一款专业的 ​原型设计工具&#xff0c;主要用于 ​网站、APP、软件等产品的界面设计和交互原型制作。 一、准备工作 ​下载好安装包​ Axure RP 9安装包下载&#xff1a;https://pan.quark.cn/s/bc2b35011106 二、开始安装 第一步&#xff1a;双击运行安装包…

AutoMQ 亮相首尔:KafkaKRU 分享日志流处理新思路

全球 Kafka 社区都在关注 AutoMQ&#xff01;凭借在 Kafka 生态的独特创新&#xff0c;AutoMQ 深受 Kafka 用户喜爱&#xff0c;已成为众多企业和开发者的首选实时数据解决方案。昨天&#xff0c;我们非常高兴看到来自韩国的 KafkaKRU 核心社区在首尔举办第2届官方线下交流会。…

从零开始使用 axum-server 构建 HTTP/HTTPS 服务

axum-server 是 Rust 生态中为 axum 框架设计的高性能服务器实现&#xff0c;基于 hyper&#xff08;底层 HTTP 引擎&#xff09;和 tower&#xff08;服务抽象&#xff09;构建&#xff0c;支持 HTTP/1、HTTP/2 及 HTTPS。本教程将从环境准备到实战功能&#xff0c;一步步带你…

电路运行的核心-RTC

1. 时钟芯片是什么&#xff1f;时钟芯片&#xff0c;更准确的名称是实时时钟芯片&#xff0c;英文是 Real-Time Clock&#xff0c;简称 RTC。它是一个专用的集成电路&#xff0c;其核心功能是追踪时间和日历。你可以把它想象成电子设备里的一个“电子表”或“日历钟”。关键特性…

AR消防头盔:火场救援的智能“透视眼”

在浓烟弥漫、能见度几乎为零的火场中&#xff0c;消防员们依靠什么来精准掌握队友的位置和状态&#xff1f;答案是AR智能消防头盔&#xff08; www.teamhelper.cn &#xff09;。这种头盔通过多种定位技术的融合&#xff0c;为消防员提供了强大的团队协作和指挥协同能力&#x…

基于大模型的个性化推荐系统实现探索与应用

前言 如果你一直在跟着Fanstuck博主的脚步探索AI大模型的相关内容&#xff0c;从最初的大模型Prompt工程解析&#xff0c;DeepSeek全面解析&#xff0c;到实际的私有化大模型开发部署&#xff0c;再到深入NL2SQL、知识图谱大模型和ChatBI等更高阶应用.我是Fanstuck&#xff0c…