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.pswp.cn/web/74584.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/74584.shtml
英文地址,請注明出處:http://en.pswp.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…