Qt进阶开发:QFileSystemModel的使用

文章目录

    • 一、QFileSystemModel的基本介绍
    • 二、QFileSystemModel的基本使用
      • 2.1 在 QTreeView 中使用
      • 2.2 在 QListView 中使用
      • 2.3 在 QTableView 中使用
    • 三、QFileSystemModel的常用API
      • 3.1 设置根目录
      • 3.2 过滤文件
        • 3.2.1 仅显示文件
        • 3.2.2 只显示特定后缀的文件
        • 3.2.3 只显示目录
    • 四、监听文件系统变化
      • 1. QFileSystemModel常见信号
      • 2. 信号的使用示例
        • 2.1 监听目录加载完成
        • 2.2 监听文件重命名
        • 2.3 监听根路径变化
        • 2.4 监听文件/目录添加
        • 2.5 监听文件/目录删除
      • 3. 动态更新QLabel显示选中文件
      • 4.右键菜单的实现
    • 五、继承QFileSystemModel并进行自定义

一、QFileSystemModel的基本介绍

  QFileSystemModel 是 Qt 框架中用于管理和显示本地文件系统的 MVC 结构中的 Model。它可以与 QTreeView、QListView 或 QTableView 结合使用,实现文件管理功能。相比 QDirModel,QFileSystemModel 只会加载需要的目录,支持懒加载,在处理大文件夹时更高效。

主要特点:

  • 继承自 QAbstractItemModel,提供标准的文件系统数据模型。
  • 懒加载(Lazy Loading):不会一次性加载整个文件系统,只会加载需要的部分,提升性能。
  • 支持文件过滤(setFilter()、setNameFilters())。
  • 自动监听文件系统变化,实时更新 UI。

二、QFileSystemModel的基本使用

2.1 在 QTreeView 中使用

#include <QApplication>
#include <QTreeView>
#include <QFileSystemModel>int main(int argc, char *argv[]) {QApplication app(argc, argv);QFileSystemModel model;model.setRootPath(QDir::homePath());  // 设置根目录QTreeView treeView;treeView.setModel(&model);treeView.setRootIndex(model.index(QDir::homePath())); // 绑定视图treeView.show();return app.exec();
}

在这里插入图片描述

2.2 在 QListView 中使用

QListView listView;
listView.setModel(&model);
listView.setRootIndex(model.index(QDir::homePath()));
listView.show();

在这里插入图片描述

2.3 在 QTableView 中使用

QTableView tableView;
tableView.setModel(&model);
tableView.setRootIndex(model.index(QDir::homePath()));
tableView.show();

在这里插入图片描述

三、QFileSystemModel的常用API

在这里插入图片描述

3.1 设置根目录

model.setRootPath(QDir::homePath());  // 设置为用户目录

注意:setRootPath() 只是设置数据模型的根目录,并不会影响 QTreeView 显示的目录。要限制 QTreeView 的显示范围,需使用 setRootIndex()。

3.2 过滤文件

3.2.1 仅显示文件
model.setFilter(QDir::Files | QDir::NoDotAndDotDot);

QDir::Files 只显示文件,QDir::NoDotAndDotDot 过滤掉 . 和 … 目录。

3.2.2 只显示特定后缀的文件
model.setNameFilters(QStringList() << "*.cpp" << "*.h");
model.setNameFilterDisables(false); // 过滤掉不符合的文件

这将只显示 .cpp 和 .h 文件。

3.2.3 只显示目录
model.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);

只显示目录,隐藏所有文件。

四、监听文件系统变化

1. QFileSystemModel常见信号

在这里插入图片描述

2. 信号的使用示例

2.1 监听目录加载完成

当 QFileSystemModel 完成某个目录的加载时,可以使用 directoryLoaded() 信号:

#include <QApplication>
#include <QTreeView>
#include <QFileSystemModel>
#include <QDebug>int main(int argc, char *argv[]) {QApplication app(argc, argv);QFileSystemModel model;QObject::connect(&model, &QFileSystemModel::directoryLoaded, [](const QString &path) {qDebug() << "目录加载完成:" << path;});model.setRootPath(QDir::homePath());QTreeView treeView;treeView.setModel(&model);treeView.setRootIndex(model.index(QDir::homePath()));treeView.show();return app.exec();
}

解释:

  • 当某个目录的内容加载完成时,会输出 “目录加载完成:/home/user”(Linux/macOS)或 “目录加载完成:C:/Users/xxx”(Windows)。
  • 适用场景:可以在目录加载完成后执行额外的操作,比如统计文件数量、更新 UI 状态等。
2.2 监听文件重命名

如果用户在文件管理器中修改了文件名,可以捕获 fileRenamed() 信号:

QObject::connect(&model, &QFileSystemModel::fileRenamed, [](const QString &path, const QString &oldName, const QString &newName) {qDebug() << "文件重命名:" << path + "/" + oldName << " -> " << newName;});

解释:

  • fileRenamed(path, oldName, newName) 提供了文件所在目录、旧文件名和新文件名。
  • 适用场景:可以记录日志、同步到数据库或通知 UI 更新。
2.3 监听根路径变化

当 setRootPath() 发生变化时,触发 rootPathChanged():

QObject::connect(&model, &QFileSystemModel::rootPathChanged, [](const QString &newPath) {qDebug() << "根目录更改为:" << newPath;});

适用场景:当用户更改文件浏览的根目录时,可以执行特定操作,比如清除旧数据、更新 UI 等。

2.4 监听文件/目录添加

当新文件或目录被创建时,会触发 rowsInserted() 信号:

QObject::connect(&model, &QFileSystemModel::rowsInserted, [&model](const QModelIndex &parent, int start, int end) {for (int row = start; row <= end; ++row) {QModelIndex index = model.index(row, 0, parent);qDebug() << "新文件/文件夹:" << model.filePath(index);}});

解释:

  • rowsInserted() 触发时,会输出新文件或目录的路径。
  • 适用场景:当用户创建新文件/文件夹时,自动执行相应的 UI 更新或日志记录。
2.5 监听文件/目录删除

当某个文件或文件夹被删除时,会触发 rowsRemoved() 信号:

QObject::connect(&model, &QFileSystemModel::rowsRemoved, [](const QModelIndex &parent, int start, int end) {qDebug() << "文件/文件夹删除:" << start << "到" << end;});

3. 动态更新QLabel显示选中文件

#include <QApplication>
#include <QTreeView>
#include <QFileSystemModel>
#include <QLabel>
#include <QVBoxLayout>
#include <QWidget>
#include <QItemSelectionModel>int main(int argc, char *argv[]) {QApplication app(argc, argv);QFileSystemModel model;model.setRootPath(QDir::homePath());QTreeView treeView;treeView.setModel(&model);treeView.setRootIndex(model.index(QDir::homePath()));QLabel label;label.setText("选中文件路径显示区域");// 监听选中项变化QObject::connect(treeView.selectionModel(), &QItemSelectionModel::selectionChanged, [&model, &treeView, &label](const QItemSelection &selected, const QItemSelection &) {if (!selected.indexes().isEmpty()) {QModelIndex index = selected.indexes().first();label.setText(model.filePath(index));}});// 设置 UI 布局QWidget window;QVBoxLayout layout;layout.addWidget(&treeView);layout.addWidget(&label);window.setLayout(&layout);window.show();return app.exec();
}

输出显示:
在这里插入图片描述

4.右键菜单的实现

可以为 QTreeView 添加右键菜单,实现文件操作(打开、删除等)。

#include <QMenu>
#include <QAction>
#include <QDesktopServices>
#include <QUrl>void onContextMenu(const QPoint &pos) {QModelIndex index = treeView.indexAt(pos);if (!index.isValid()) return;QMenu menu;QAction *openAction = new QAction("打开", &menu);QAction *deleteAction = new QAction("删除", &menu);connect(openAction, &QAction::triggered, [index, &model]() {QString path = model.filePath(index);QDesktopServices::openUrl(QUrl::fromLocalFile(path));});connect(deleteAction, &QAction::triggered, [index, &model]() {model.remove(index);});menu.addAction(openAction);menu.addAction(deleteAction);menu.exec(treeView.viewport()->mapToGlobal(pos));
}

五、继承QFileSystemModel并进行自定义

继承 QFileSystemModel 并进行自定义,可以用来修改文件显示方式、拦截用户操作、隐藏某些文件或添加额外的功能。
可以通过继承 QFileSystemModel来:

  • 自定义文件名显示(如:在文件名前加上 [文件] 或 [目录])。
  • 自定义文件图标。
  • 隐藏某些文件/目录。
  • 拦截文件删除或重命名操作。

示例 1:重写 data() 修改文件显示
默认情况下,QFileSystemModel 只显示文件名。如果我们想要修改显示内容(如:文件名前加上类型信息),可以重写 data() 方法:

#include <QFileSystemModel>
#include <QDebug>class CustomFileSystemModel : public QFileSystemModel {
public:explicit CustomFileSystemModel(QObject *parent = nullptr) : QFileSystemModel(parent) {}QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override {if (!index.isValid()) return QVariant();if (role == Qt::DisplayRole) {  // 修改显示文本QString fileName = QFileSystemModel::data(index, Qt::DisplayRole).toString();if (isDir(index))return "[目录] " + fileName;elsereturn "[文件] " + fileName;}return QFileSystemModel::data(index, role);}
};

示例 2:自定义文件图标
如果想要为特定类型的文件设置不同的图标(如 .txt 用文本图标,.cpp 用代码图标),可以重写 data() 的 Qt::DecorationRole:

#include <QFileIconProvider>
#include <QFileInfo>class CustomFileSystemModel : public QFileSystemModel {
public:explicit CustomFileSystemModel(QObject *parent = nullptr) : QFileSystemModel(parent) {}QVariant data(const QModelIndex &index, int role = Qt::DecorationRole) const override {if (!index.isValid()) return QVariant();if (role == Qt::DecorationRole) {QFileInfo fileInfo = this->fileInfo(index);if (fileInfo.suffix() == "txt")return QIcon(":/icons/text.png"); // 替换为你的图标else if (fileInfo.suffix() == "cpp" || fileInfo.suffix() == "h")return QIcon(":/icons/code.png"); // 替换为你的图标else if (fileInfo.isDir())return QIcon(":/icons/folder.png"); // 替换为你的文件夹图标}return QFileSystemModel::data(index, role);}
};

示例 2:自定义双击打开文件
如果希望在双击文件时执行特定操作(如:打开文件或显示信息),可以在 QTreeView 中监听 doubleClicked() 信号:

QObject::connect(&treeView, &QTreeView::doubleClicked, [&](const QModelIndex &index) {QString filePath = model.filePath(index);if (model.isDir(index)) {qDebug() << "双击打开目录:" << filePath;} else {qDebug() << "双击打开文件:" << filePath;QDesktopServices::openUrl(QUrl::fromLocalFile(filePath));}
});

下面是一个完整的示例,将以上功能整合到 QTreeView 中:

#include <QApplication>
#include <QTreeView>
#include <QFileSystemModel>
#include <QVBoxLayout>
#include <QWidget>
#include <QMessageBox>
#include <QDesktopServices>
#include <QUrl>class CustomFileSystemModel : public QFileSystemModel {
public:explicit CustomFileSystemModel(QObject *parent = nullptr) : QFileSystemModel(parent) {}QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override {if (!index.isValid()) return QVariant();if (role == Qt::DisplayRole) {QString fileName = QFileSystemModel::data(index, Qt::DisplayRole).toString();return isDir(index) ? "[目录] " + fileName : "[文件] " + fileName;}return QFileSystemModel::data(index, role);}
};int main(int argc, char *argv[]) {QApplication app(argc, argv);CustomFileSystemModel model;model.setRootPath(QDir::homePath());QTreeView treeView;treeView.setModel(&model);treeView.setRootIndex(model.index(QDir::homePath()));QObject::connect(&treeView, &QTreeView::doubleClicked, [&](const QModelIndex &index) {QString filePath = model.filePath(index);QDesktopServices::openUrl(QUrl::fromLocalFile(filePath));});treeView.resize(800, 600);treeView.show();return app.exec();
}

在这里插入图片描述

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

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

相关文章

KAPC的前世今生--(下)下RPCRT4!NMP_SyncSendRecv函数分析

第一部分&#xff1a;nt!KiDeliverApc函数调用nt!IopCompleteRequest函数后准备返回 1: kd> kv # ChildEBP RetAddr Args to Child 00 ba3eec18 80a3c83b 896e4e40 ba3eec64 ba3eec58 nt!IopCompleteRequest0x3a3 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv…

深入理解C++引用:从基础到现代编程实践

一、引用的本质与基本特性 1.1 引用定义 引用是为现有变量创建的别名&#xff0c;通过&符号声明。其核心特点&#xff1a; 必须初始化且不能重新绑定 与被引用变量共享内存地址 无独立存储空间&#xff08;编译器实现&#xff09; 类型必须严格匹配 int value 42; in…

嵌入式Linux开发环境搭建,三种方式:虚拟机、物理机、WSL

目录 总结写前面一、Linux虚拟机1 安装VMware、ubuntu18.042 换源3 改中文4 中文输入法5 永不息屏6 设置 root 密码7 安装 terminator8 安装 htop&#xff08;升级版top&#xff09;9 安装 Vim10 静态IP-虚拟机ubuntu11 安装 ssh12 安装 MobaXterm &#xff08;SSH&#xff09;…

软件工程面试题(二十七)

1、j a v a 对象初始化顺序 1.类的初始化(initialization class & interface) 2.对象的创建(creation of new class instances) 顺序:应为类的加载肯定是第一步的,所以类的初始化在前。大体的初始化顺序是: 类初始化 -> 子类构造函数 -> 父类构造函数 -&g…

《AI大模型开发笔记》MCP快速入门实战(一)

目录 1. MCP入门介绍 2. Function calling技术回顾 3. 大模型Agent开发技术体系回顾 二、 MCP客户端Client开发流程 1. uv工具入门使用指南 1.1 uv入门介绍 1.2 uv安装流程 1.3 uv的基本用法介绍 2.MCP极简客户端搭建流程 2.1 创建 MCP 客户端项目 2.2 创建MCP客户端…

Java中的正则表达式Lambda表达式

正则表达式&&Lambda表达式 正则表达式和Lambda表达式是Java编程中两个非常实用的特性。正则表达式用于字符串匹配与处理&#xff0c;而Lambda表达式则让函数式编程在Java中变得更加简洁。本文将介绍它们的基本用法&#xff0c;并结合示例代码帮助理解。同时要注意&…

Talend API Tester

背景 工作中有时会需要调测http接口&#xff0c;postman无疑是最常用最流行的工具&#xff0c;但是有一个致命问题&#xff0c;必须要登录&#xff0c;而工作经常是私网环境&#xff0c;导致使用非常不方便。因此想找一个Windows系统上的轻量级、无需登录即可使用的http测试工…

leetcode数组-移除元素

题目 题目链接&#xff1a;https://leetcode.cn/problems/remove-element/ 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。 假设 nums 中不等于 val 的元素数量为…

什么是市盈率,通俗解释清楚

市盈率就是“股价和公司盈利能力”的一个比例关系&#xff0c;简单来说&#xff0c;就是你花多少钱买股票&#xff0c;要等多少年才能通过公司赚的钱“回本”。 假设你买了一家公司的股票&#xff0c;花了100块钱&#xff0c;这家公司每年能赚10块钱。那市盈率就是100除以10&am…

突破传统认知:聚类算法的底层逻辑与高阶应用全景解析

一、维度革命&#xff1a;重新定义聚类分析的认知边界 在人工智能的浩瀚星空中&#xff0c;聚类算法犹如一组精密的星际导航仪&#xff0c;帮助我们在无序的数据宇宙中发现隐藏的秩序。这项起源于人类本能分类需求的技术&#xff0c;经历了从简单分组到智能识别的蜕变&#xf…

【愚公系列】《高效使用DeepSeek》051-产品创新研发

🌟【技术大咖愚公搬代码:全栈专家的成长之路,你关注的宝藏博主在这里!】🌟 📣开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主! 👉 江湖人称"愚公搬代码",用七年如一日的精神深耕技术领域,以"…

网络编程—Socket套接字(UDP)

上篇文章&#xff1a; 网络编程—网络概念https://blog.csdn.net/sniper_fandc/article/details/146923380?fromshareblogdetail&sharetypeblogdetail&sharerId146923380&sharereferPC&sharesourcesniper_fandc&sharefromfrom_link 目录 1 概念 2 Soc…

深度学习deeplearn1

import torch # 导入 PyTorch 库&#xff0c;PyTorch 是一个用于深度学习和张量计算的强大库x torch.arange(12) # 创建一个包含从 0 到 11 的整数的一维张量 x # torch.arange 函数用于生成一个指定范围的整数序列print(x) # 打印张量 x 的内容print(x.shape) # 打印张量 x 的…

无线通信技术(三):5G NR通信频带划分与应用场景

目录 一.5G NR频带划分概述 二.全球运营商5G频带分配对比 三.5G频带的应用场景 5G网络的发展离不开频谱资源的合理分配。不同的频段决定了5G的覆盖范围、传输速率和应用场景。本文将系统介绍5G NR频带划分,并结合实际应用场景,理解不同频段的特性及其适用环境。 …

观察者模式在Java单体服务中的运用

观察者模式主要用于当一个对象发生改变时&#xff0c;其关联的所有对象都会收到通知&#xff0c;属于事件驱动类型的设计模式&#xff0c;可以对事件进行监听和响应。下面简单介绍下它的使用&#xff1a; 1 定义事件 import org.springframework.context.ApplicationEvent;pu…

YOLO 获取 COCO 指标终极指南 | 从标签转换到 COCOAPI 评估 (训练/验证) 全覆盖【B 站教程详解】

✅ YOLO 轻松获取论文 COCO 指标&#xff1a;AP&#xff08;small&#xff0c;medium&#xff0c;large &#xff09;| 从标签转换到 COCOAPI 评估 (训练/验证) 全覆盖 文章目录 一、摘要二、为什么需要 COCO 指标评估 YOLO 模型&#xff1f;三、核心挑战与解决方案 (视频教程核…

[C/C++]文件输入输出

C style FILE * fileptr filename"C:\\file.txt" fopenfclosefprintfC style //指向std::ostream的指针 #include <iostream> #include <fstream>int main() {std::ostream* output &std::cout; // 默认指向控制台// 输出到控制台*output <&l…

【Android】界面布局-线性布局-例子

线性布局&#xff08;LinearLayout&#xff09;是一种重要的界面布局中&#xff0c;也是经常使用到的一种界面布局 • 在线性布局中&#xff0c;所有的子元素都按照垂直或水平的顺序在界面上排列 ➢如果垂直排列&#xff0c;则每行仅包含一个界面元素 ➢如果水平排列&…

HTML表单属性1

value 属性 value 设置输入字段的初始值&#xff08;默认值&#xff09;,提交表单时&#xff0c;如果用户未做修改&#xff0c;将发送value中的默认值 <form action"#">First name: <br><input type"text" name"firstname" val…

JavaScrip图标工具Chart.js之 气泡图

气泡图用于展示三个变量之间的关系。 气泡的位置由前两个变量决定&#xff0c;对应的是 X 轴和 Y 轴&#xff0c;第三个参数为气泡的大小。 {// X 轴对应值x: number,// Y 轴对应值y: number,// 气泡半径&#xff0c;单位为像素r: number } 泡图的 type 属性为 bubble &#xf…