UE4 Slate控件之TreeView 使用例子(一)

TreeView例子

先从Contruct中往子Slot添加Widget,先声明指向STreeView的指针,后续方便进行视图的一些操作

	TSharedPtr<STreeView<TSharedPtr<FString>>> TreeBeingTested;
	TArray<TSharedPtr<FString>> Items;

.ItemHeight,.TreeItemsSource,.OnGenerateRow,通过跳到对应的声明处,可以知道这有些是通过SLATE_BEGIN_ARGS或SLATE_EVENT声明注入的,就需要通过.XXX(YYY)的方式初始化,TreeView有些EVENT是必须要有初始化的,不然会报错,例如OnGetChildren,

ChildSlot
	[
		SNew(SVerticalBox)
		+ SVerticalBox::Slot()
		[
			SNew(SVerticalBox)
			+ SVerticalBox::Slot()
			[
				SNew(SBorder)
				.BorderImage(FCoreStyle::Get().GetBrush("ToolPanel.GroupBorder"))
				[
					SAssignNew(TreeBeingTested, STreeView< TSharedPtr<FString> >)
					.ItemHeight(24)
					.TreeItemsSource(&Items)
					.OnGenerateRow(this, &SSkillLogTreeWidgetItem::OnGenerateWidgetForTree)
					.OnGetChildren(this, &SSkillLogTreeWidgetItem::OnGetChildrenForTree)
					.WheelScrollMultiplier(60.f)
					.OnSelectionChanged(this, &SSkillLogTreeWidgetItem::OnSelectionChanged)
					.HeaderRow
					(
						SNew(SHeaderRow)
						+ SHeaderRow::Column(Args._ColumnName).FixedWidth(150.0f).DefaultLabel(Args._ColumnLabel)
					)
				]
			]
		]
	];

ArgumentType就是我们在STreeView进行New时候写的

所以OnGetChildren函数就是

当选择元素的时候会执行的事件,此处很多函数内部都是用SLATE_EVENT进行前置声明,只需要在SAssignNew或SNew的时候,通过.XXX=(XXXXX)实现事件功能

void SSkillLogTreeWidgetItem::OnSelectionChanged(TSharedPtr<FString> Item, ESelectInfo::Type SelectInfo)
{
   if (!Item.IsValid())
      return;

   UpDateWidgetItemByColumnAndID(ColumnName.ToString(), **Item.Get());
}

为TreeView生成每一个Widget,也就是每一行

TSharedRef<ITableRow> SSkillLogTreeWidgetItem::OnGenerateWidgetForTree(TSharedPtr<FString> InItem,
                                                                       const TSharedRef<STableViewBase>& OwnerTable)
{
	return SNew(SSkillLogItemEditor, OwnerTable).ItemToEdit(InItem);
}

因为每一行的元素都要看成一个个体,也就是类的实例,当多Column的时候需要类需要继承SMultiColumnTableRow

class SSkillLogItemEditor : public SMultiColumnTableRow<TSharedPtr<FString>>
{
public:
	SLATE_BEGIN_ARGS(SSkillLogItemEditor) : _ItemToEdit()
		{}

		SLATE_EVENT(FOnCanAcceptDrop, OnCanAcceptDrop)
	
		SLATE_EVENT(FOnAcceptDrop, OnAcceptDrop)
	
		SLATE_EVENT(FOnDragDetected, OnDragDetected)

		SLATE_ARGUMENT(TSharedPtr<FString>, ItemToEdit)

	SLATE_END_ARGS()

	void Construct( const FArguments& InArgs, const TSharedRef<STableViewBase>& InOwnerTableView);
	
	virtual TSharedRef<SWidget> GenerateWidgetForColumn(const FName& ColumnName) override;

	FText GetID() const;

private:
	TSharedPtr<FString> ItemToEdit;
};

这个地方可以用ColumnName生成不同的TextBlock

void SSkillLogItemEditor::Construct(const FArguments& InArgs, const TSharedRef<STableViewBase>& InOwnerTableView)
{
	ItemToEdit = InArgs._ItemToEdit;

	FSuperRowType::Construct(FSuperRowType::FArguments().Padding(0), InOwnerTableView);
}

TSharedRef<SWidget> SSkillLogItemEditor::GenerateWidgetForColumn(const FName& ColumnName)
{
	const FSlateFontInfo ItemEditorFont = FCoreStyle::Get().GetFontStyle(TEXT("NormalFont"));

	return SNew(SHorizontalBox)
		+ SHorizontalBox::Slot()
		.AutoWidth()
		[
			SNew(SExpanderArrow, SharedThis(this))
    			.IndentAmount(16)
    			.ShouldDrawWires(true)
		]
		+ SHorizontalBox::Slot()
		[
			SNew(STextBlock).Font(ItemEditorFont).Text(this, &SSkillLogItemEditor::GetID).Margin(5)
		];
}

FText SSkillLogItemEditor::GetID() const
{
	ensure(ItemToEdit.IsValid());
	return FText::FromString(*ItemToEdit.Get());
}

后续完善再添加更多例子~

posted @ 2021-08-11 10:46  shadow_lr  阅读(1564)  评论(0编辑  收藏  举报