You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从文件路径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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 15:27:41