UE4+C++开发-(九十九)-C++根据一个文件夹结构,生成对应的TreeView

王者杯·14天创作挑战营·第5期 10w+人浏览 1.1k人参与

   可以根据文件夹列表生成节点行 UI,核心是通过 递归遍历文件夹结构 构建树形节点数据,再关联到 TreeView 的生成逻辑中。以下是具体实现方案,保持原有 TreeView 框架不变,仅修改数据初始化和节点生成部分:

1. 新增文件夹遍历工具函数(用于构建节点数据)

.cpp文件中添加递归遍历文件夹的函数,将文件夹结构转换为FDynamicTreeNode树形结构:

cpp

运行

// 递归遍历文件夹,生成树形节点
void SDynamicTreeViewWidget::AddFolderToNode(const FString& FolderPath, TSharedPtr<FDynamicTreeNode> ParentNode)
{
    if (!FPaths::DirectoryExists(FolderPath))
        return;

    // 获取当前文件夹名称(作为节点名称)
    FString FolderName = FPaths::GetCleanFilename(FolderPath);
    TSharedPtr<FDynamicTreeNode> CurrentNode = MakeShareable(new FDynamicTreeNode(FolderName, ParentNode));

    if (ParentNode.IsValid())
    {
        ParentNode->Children.Add(CurrentNode);  // 作为子节点添加
    }
    else
    {
        RootNodes.Add(CurrentNode);  // 作为根节点添加
    }

    // 遍历子文件夹
    TArray<FString> SubFolders;
    IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
    FDirectoryVisitor Visitor = FDirectoryVisitor::CreateLambda([&](const TCHAR* Path, bool bIsDirectory)
    {
        if (bIsDirectory && Path != FolderPath)  // 只处理子文件夹(排除当前文件夹)
        {
            SubFolders.Add(Path);
            return true;  // 继续遍历
        }
        return true;
    });

    PlatformFile.IterateDirectory(*FolderPath, Visitor);

    // 递归处理子文件夹
    for (const FString& SubFolder : SubFolders)
    {
        AddFolderToNode(SubFolder, CurrentNode);
    }
}

2. 修改节点初始化方法(从文件夹列表生成)

将原InitRootNodes改为从目标文件夹路径初始化:

cpp

运行

void SDynamicTreeViewWidget::InitRootNodes()
{
    RootNodes.Empty();

    // 目标文件夹路径(可替换为你的文件夹路径,支持多个根文件夹)
    TArray<FString> RootFolderPaths = {
        FPaths::ProjectContentDir() + TEXT("YourFolder1"),  // 项目Content下的文件夹1
        FPaths::ProjectDir() + TEXT("YourFolder2")         // 项目根目录下的文件夹2
    };

    // 遍历所有根文件夹,生成节点
    for (const FString& RootFolder : RootFolderPaths)
    {
        AddFolderToNode(RootFolder, nullptr);  // 第二个参数为nullptr表示添加为根节点
    }
}

3. 保持 UI 生成逻辑不变(自动适配文件夹节点)

OnGenerateTreeRowOnGetChildren无需修改,会自动根据文件夹生成的节点数据显示层级结构:

cpp

运行

// 生成节点行UI(无需修改,自动显示文件夹名称)
TSharedRef<ITableRow> SDynamicTreeViewWidget::OnGenerateTreeRow(
    TSharedPtr<FDynamicTreeNode> InItem, 
    const TSharedRef<STableViewBase>& OwnerTable
)
{
    return SNew(STableRow<TSharedPtr<FDynamicTreeNode>>, OwnerTable)
        .Content()
        [
            SNew(STextBlock)
            .Text(FText::FromString(InItem->NodeName))  // 显示文件夹名称
            .Font(FSlateFontInfo(TEXT("C:/Windows/Fonts/msyh.ttc"), 14))
            .Margin(FMargin(4.0f * InItem->GetDepth(), 4.0f))  // 按层级缩进
        ];
}

// 获取子节点(无需修改,自动返回子文件夹节点)
void SDynamicTreeViewWidget::OnGetTreeChildren(
    TSharedPtr<FDynamicTreeNode> InItem, 
    TArray<TSharedPtr<FDynamicTreeNode>>& OutChildren
)
{
    if (InItem.IsValid())
    {
        OutChildren = InItem->Children;  // 子文件夹节点
    }
}

4. 核心逻辑说明

  1. 文件夹遍历
    通过IPlatformFile递归遍历指定文件夹路径,获取所有子文件夹,每级文件夹对应一个FDynamicTreeNode节点。

  2. 节点结构映射

    • 根文件夹 → TreeView 根节点
    • 子文件夹 → 对应父节点的子节点
    • 文件夹名称 → 节点显示文本
  3. UI 自动适配
    原 TreeView 的 UI 生成逻辑(OnGenerateTreeRow)会根据节点的NodeName(文件夹名)和GetDepth(层级深度)自动显示缩进和文本,无需额外修改。

5. 使用方法

  • 替换RootFolderPaths中的路径为你的目标文件夹(支持绝对路径或 UE 路径宏,如FPaths::ProjectContentDir());
  • 编译后,TreeView 会自动显示文件夹的层级结构,点击节点前的箭头可展开 / 折叠子文件夹。

扩展优化(可选)

  • 显示文件夹图标:在STextBlock前添加SImage,使用 UE 内置文件夹图标(FEditorStyle::Get().GetBrush("ContentBrowser.FolderIcon"));
  • 过滤特定文件夹:在AddFolderToNode中添加判断,跳过不需要显示的文件夹(如.gitBinaries等);
  • 支持文件显示:修改遍历逻辑,同时获取文件,用不同节点类型区分文件夹和文件(添加bIsFile标志)。

通过以上修改,TreeView 会完全根据文件夹列表动态生成节点 UI,保持原有交互逻辑的同时实现文件夹结构可视化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值