本文将介绍自定义Slate控件的方法、向控件传递参数的方法,以及SButton事件响应背后的原理。
使用类向导添加一个SCompoundWidget类型的控件,命名为“SCustomWidget”,添加如下代码:
SCustomWidget.h:
#pragma once
#include "CoreMinimal.h"
#include "Widgets/SCompoundWidget.h"
#include "DeclarativeSyntaxSupport.h"
// 声明一个委托
DECLARE_DELEGATE_OneParam(FOnButtonDown, FString)
class HELLOSLATE_API SCustomWidget : public SCompoundWidget
{
public:
SLATE_BEGIN_ARGS(SCustomWidget)
{
_Message = TEXT("Hello");// 这样设置参数的默认值
}
// 将要传递的参数放到反射系统,这样就可以在SNew之后为该变量赋值
SLATE_EVENT(FOnButtonDown, OnButtonDown)
SLATE_ARGUMENT(FString, Message)
SLATE_END_ARGS()
/** Constructs this widget with InArgs */
void Construct(const FArguments& InArgs);
// 重写OnMouseButtonDown函数,在这里执行委托
virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
// 声明要传递的参数
FOnButtonDown OnButtonDown;
FString Message;
};
SCustomWidget.cpp:
#include "SCustomWidget.h"
#include "SlateOptMacros.h"
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SCustomWidget::Construct(const FArguments& InArgs)
{
// 赋予传入的值
OnButtonDown = InArgs._OnButtonDown;
Message = InArgs._Message;
/*
ChildSlot
[
// Populate the widget
];
*/
}
FReply SCustomWidget::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
OnButtonDown.ExecuteIfBound(Message);
return FReply::Handled();
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
在SStandardSlateWidget中构建该控件并传入参数:
SStandardSlateWidget.h:
#pragma once
#include "CoreMinimal.h"
#include "Widgets/SCompoundWidget.h"
#include "DeclarativeSyntaxSupport.h"
class HELLOSLATE_API SStandardSlateWidget : public SCompoundWidget
{
public:
SLATE_BEGIN_ARGS(SStandardSlateWidget)
{}
SLATE_END_ARGS()
/** Constructs this widget with InArgs */
void Construct(const FArguments& InArgs);
// 这个是用来绑定到委托上的函数
void ShowMessage(FString inMessage);
};
SStandardSlateWidget.cpp:
#include "SStandardSlateWidget.h"
#include "SlateOptMacros.h"
#include "SCustomWidget.h"
#include "MessageDialog.h"
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SStandardSlateWidget::Construct(const FArguments& InArgs)
{
ChildSlot
[
SNew(SCustomWidget)
.Message("Hello World!")// 传入普通变量
.OnButtonDown(this, &SStandardSlateWidget::ShowMessage)// 传入委托
];
}
void SStandardSlateWidget::ShowMessage(FString inMessage)
{
FMessageDialog::Open(EAppMsgType::Ok, FText::FromString(inMessage));
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
效果如下:
查看SButton的源码,可以看到如下:
/** Called when the button is clicked */
SLATE_EVENT( FOnClicked, OnClicked )
/** Called when the button is pressed */
SLATE_EVENT( FSimpleDelegate, OnPressed )
/** Called when the button is released */
SLATE_EVENT( FSimpleDelegate, OnReleased )
SLATE_EVENT( FSimpleDelegate, OnHovered )
SLATE_EVENT( FSimpleDelegate, OnUnhovered )
可以看出,Slate预置的控件均是采用这种方式传递事件。