如何从文件路径QStringList创建QStandardItemModel实现QTreeView展示?
直接从路径列表构建QStandardItemModel实现树形文件结构
嘿,作为C++和Qt新手碰到这种效率问题太正常了——用临时目录模拟树形结构的方法虽然直观,但一万多个文件的磁盘IO开销确实会拖垮性能。直接在内存里用QStandardItemModel构建树形结构才是正确的方向,我给你详细讲讲怎么实现:
核心思路
我们要把每个路径按/拆分成层级节点(比如Arena/Main/00078/a.txt拆成Arena→Main→00078→a.txt),然后逐层往模型里添加节点,关键是要复用已经创建的父节点,避免重复创建相同的文件夹节点,这样能保证处理大量路径时的效率。
完整实现代码
首先写一个工具函数来批量构建模型:
#include <QStandardItemModel> #include <QStandardItem> #include <QStringList> void buildTreeModel(QStandardItemModel* model, const QStringList& filePaths) { // 确保模型初始化为单列(只显示名称) model->setColumnCount(1); model->setHeaderData(0, Qt::Horizontal, "文件结构"); for (const QString& path : filePaths) { // 拆分路径为各个层级,过滤空字符串(避免路径首尾的/导致空项) QStringList parts = path.split('/', Qt::SkipEmptyParts); if (parts.isEmpty()) continue; // 从根节点开始遍历 QStandardItem* currentParent = model->invisibleRootItem(); for (const QString& part : parts) { // 检查当前父节点下是否已经存在同名子节点 bool found = false; for (int i = 0; i < currentParent->rowCount(); ++i) { QStandardItem* child = currentParent->child(i); if (child->text() == part) { currentParent = child; found = true; break; } } // 如果没找到,就创建新节点并添加到父节点下 if (!found) { QStandardItem* newItem = new QStandardItem(part); // 可以根据是否是最后一个节点设置图标(可选) if (&part == &parts.last()) { // 设置文件图标,比如用QFileIconProvider获取 // QFileIconProvider iconProvider; // newItem->setIcon(iconProvider.icon(QFileIconProvider::File)); } else { // 设置文件夹图标 // newItem->setIcon(iconProvider.icon(QFileIconProvider::Folder)); } currentParent->appendRow(newItem); currentParent = newItem; } } } }
然后在你的主代码里调用这个函数,关联到QTreeView:
// 初始化模型和树形视图 QStandardItemModel* treeModel = new QStandardItemModel(this); QTreeView* treeView = new QTreeView(this); // 你的路径列表 QStringList paths = { "Arena/Main/00078/a.txt", "Arena/Main/00080/b.txt", "Arena/Main/00080/collision/c.txt", "Arena/Main/00080/light/d.txt", "Arena/Main/00081/e.txt", "Characters/f.txt", "Characters/Main/g.txt", "Characters/Main/someFolder/h.txt" }; // 构建模型 buildTreeModel(treeModel, paths); // 关联模型到视图 treeView->setModel(treeModel); // 可选:隐藏表头、自动展开节点等 treeView->setHeaderHidden(true); treeView->expandAll(); // 如果需要默认展开所有节点
关键优化点
- 复用父节点:每次创建节点前先检查是否已存在,避免重复创建相同的文件夹节点,这是处理大量路径时效率的核心保障;
- 内存操作:完全在内存中构建,没有磁盘IO开销,处理1万+路径会比临时目录方法快得多;
- 可选的图标设置:可以用
QFileIconProvider给文件和文件夹添加对应的系统图标,让界面和QFileSystemModel的效果更一致。
这样实现后,你的QTreeView就能展示和之前一样的树形结构,而且性能会有质的提升~
内容的提问来源于stack exchange,提问作者DeadInStock
相关产品推荐
相关产品推荐

