UE5 Slate中的StreeView的基础创建方法

cpp 复制代码
.h
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Widgets/SCompoundWidget.h"

/**
 * 
 */
class MYALONESLATE_API SMyTreeView : public SCompoundWidget
{
public:
	SLATE_BEGIN_ARGS(SMyTreeView)
		{
		}

	SLATE_ARGUMENT(FText,buttontext)

	SLATE_END_ARGS()

	/** Constructs this widget with InArgs */
	void Construct(const FArguments& InArgs);

	TSharedRef<ITableRow> OnGenerateRowForList(TSharedPtr<FString> Item, const TSharedRef<STableViewBase>& OwnerTable);
	void OnGetChildrenForTree(TSharedPtr<FString> Item, TArray<TSharedPtr<FString>>& OutChildren);

private:
	TArray<TSharedPtr<FString>> Items;
	
	TMap<FString, TArray<TSharedPtr<FString>>> ChildrenMap;
};
cpp 复制代码
.cpp

// Fill out your copyright notice in the Description page of Project Settings.


#include "MyTreeView.h"

#include "SlateOptMacros.h"

BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION

void SMyTreeView::Construct(const FArguments& InArgs)
{
	// 初始化根节点
	Items.Add(MakeShared<FString>("thisA"));
	Items.Add(MakeShared<FString>("thisB"));
	Items.Add(MakeShared<FString>("thisC"));

	// 初始化子节点
	ChildrenMap.Add("thisA", TArray<TSharedPtr<FString>>{ MakeShared<FString>("thisAaaa") });
	ChildrenMap.Add("thisB", TArray<TSharedPtr<FString>>{ MakeShared<FString>("thisBaaa"), MakeShared<FString>("thisBbbb") });
	ChildrenMap.Add("thisC", TArray<TSharedPtr<FString>>{ MakeShared<FString>("thisCaaa") });

	ChildSlot
	[
		SNew(STreeView<TSharedPtr<FString>>)
		.TreeItemsSource(&Items) // Items是一个包含TSharedPtr<FString>的数组
		.OnGenerateRow(this, &SMyTreeView::OnGenerateRowForList)
		.OnGetChildren(this, &SMyTreeView::OnGetChildrenForTree)
	];
}

TSharedRef<ITableRow> SMyTreeView::OnGenerateRowForList(TSharedPtr<FString> Item,
	const TSharedRef<STableViewBase>& OwnerTable)
{
	return SNew(STableRow<TSharedPtr<FString>>, OwnerTable)
   [
	   SNew(STextBlock)
	   .Text(FText::FromString(*Item))
	   .Font(FSlateFontInfo(FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Regular.ttf"), 24)) // 设置字体大小为24
   ];
}

void SMyTreeView::OnGetChildrenForTree(TSharedPtr<FString> Item, TArray<TSharedPtr<FString>>& OutChildren)
{
	const TArray<TSharedPtr<FString>>* FoundChildren = ChildrenMap.Find(*Item);
	if (FoundChildren)
	{
		OutChildren = *FoundChildren;
	}
}




END_SLATE_FUNCTION_BUILD_OPTIMIZATION

STableRowGetExpanderIndentPadding函数控制根节点前的默认图标,要修改需要创建一个继承至STableRow的类,通过重写GetExpanderWidget函数来改变展开和折叠的图标。需要将"ClassIcon.Plus""ClassIcon.Minus"替换为自己的样式。

cpp 复制代码
class SMyTableRow : public STableRow<TSharedPtr<FString>>
{
public:
    SLATE_BEGIN_ARGS(SMyTableRow) {}
    SLATE_END_ARGS()

    void Construct(const FArguments& InArgs, const TSharedRef<STableViewBase>& InOwnerTableView)
    {
        STableRow::Construct(
            STableRow::FArguments()
            .Style(FCoreStyle::Get(), "NoBorder")
            .ShowSelection(false),
            InOwnerTableView);
    }

    virtual TSharedRef<SWidget> GenerateWidgetForColumn(const FName& ColumnName) override
    {
        return SNew(STextBlock).Text(FText::FromString(*Item));
    }

    virtual TSharedRef<SWidget> GetExpanderWidget() override
    {
        return SNew(SImage)
        .Image(this, &SMyTableRow::GetExpanderImage);
    }

    const FSlateBrush* GetExpanderImage() const
    {
        static FSlateBrush PlusImage = FSlateIconFinder::FindIconBrushForClass("ClassIcon.Plus");
        static FSlateBrush MinusImage = FSlateIconFinder::FindIconBrushForClass("ClassIcon.Minus");

        return IsItemExpanded() ? &MinusImage : &PlusImage;
    }
};

然后在OnGenerateRowForList函数中使用SMyTableRow来替换STableRow

复制代码
TSharedRef<ITableRow> SMyTreeView::OnGenerateRowForList(TSharedPtr<FString> Item, const TSharedRef<STableViewBase>& OwnerTable)
{
    return SNew(SMyTableRow, OwnerTable)
    .Item(Item);
}
相关推荐
zhangzhangkeji6 天前
UE5 C++(71):文件是否存在,文件夹是否存在,FPaths :: FileExists( const FString & InPath) ;
ue5
妙为6 天前
UE5角色穿过石头穿模
ue5·unreal engine5·角色穿越石头·穿模
技术策划Boring7 天前
2025年工作复盘:开放世界3A项目配置管线与性能监控的探索
游戏·ue5·虚幻·p4·perforce
zhangzhangkeji9 天前
UE5 C++(70-2):定义成员函数 getCleanDirectory(..) 和枚举类 EFileDirectoryType,来获得目录
ue5
avi911110 天前
UE4-UE5虚幻引擎-前置学习三,优化,基础CPP
ue5·ue4·游戏开发·虚幻·游戏优化·游戏代码
zhangzhangkeji10 天前
UE5线程进阶(3-2):任务图的相关源码整理。 FGraphEvent 与 TGraphTask 的区别和联系
ue5
zhangzhangkeji11 天前
UE5线程进阶(3-1):
ue5
zhangzhangkeji12 天前
UE5线程进阶(2-3):enum ENamedThreads命名空间 :: Type : int32 { RHIThread = 0 } 是渲染硬件接口线程
ue5
zhangzhangkeji13 天前
UE5线程进阶(2-1):枚举类EAsyncExecution,作业类TAsyncRunnable、TAsyncQueuedWork,及全局线程函数 Async(..),及线程调用的 4 种方法总结
ue5
zhangzhangkeji13 天前
UE5线程进阶(1):
ue5