Slate 基础控件

发布于 2022-07-29  352 次阅读


Slate 基础控件

Slate 是完全自定义、与平台无关的用户界面框架,旨在让工具和应用程序(比如虚幻编辑器)的用户界面或游戏中用户界面的构建过程变得有趣、高效。它将声明性语法与轻松设计、布局和风格组件的功能相结合,允许在UI上轻松实现创建和迭代。
Slate UI解决方案使得为工具和应用程序组合图形用户界面和快速迭代这些界面变得极其简单。
UE4 的 编辑器都是建立在 Slate整个框架下,包括UE4 用于Runtime游戏的 UMG 也是基于Slate系统的。

开发过程中,对于细节面板,基于 UPROPERTY 说明符,很多 UI 功能已经足够了,但或多或少在开发过程中也会遇到需要自定义功能的时候,可能并非细节面板,也可能是细节面板的自定义需求,此时或许会遇到需要自定义控件的状况,因此,记录此文总结各个小控件的用法(虽然难用,但也没办法额 ~ )

插件开发流程可以查看这里:UE 插件开发流程
UPROPERTY 说明符可以看这里:UPROPERTY 说明符示例

Slate 宏

  • [ ] 待办
    生成控件时,我们经常会使用到一些 Slate 的宏
  • [ ] 作用,调用时机

SLATE_ATTRIBUTE

  • Use this macro to add a attribute to the declaration of your widget.
  • An attribute can be a value or a function.

SLATE_ARGUMENT

  • Use this macro to declare a slate argument.
  • Arguments differ from attributes in that they can only be values

SLATE_EVENT

  • Use this macro to add event handler support to the declarative syntax of your widget.
  • It is expected that the widget has a delegate called of type 'EventDelegateType' that is
  • named 'EventName'.

SLATE_NAMED_SLOT

  • Use this macro to add support for named slot properties such as Content and Header. See NamedSlotProperty for more details.
  • NOTE: If you're using this within a widget class that is templated, then you might have to specify a full name for the declaration.

一、按钮

1. 创建
    SNew(SHorizontalBox)
    +SHorizontalBox::Slot()
    .FillWidth(1.0f)
    [
        SNew(SButton)
        .Text(LOCTEXT("TestButton", "测试按钮"))
        .OnClicked(this, &FTestDetails::TestButtonClicked)
    ]

Slate 语法中,有两种生成控件实例的方法,分别是 SNew 与 SAssignNew,SNew 会返回控件实例指针,SAssignNEW 则需要以入参传入控件指针。
上述代码中,我们以 SNew 方式创建了一个 Button,并指定了 OnClicked 触发的方法 TestButtonClicked。

2. 委托

当 UI 上的按钮被按下时,此处我们指定的方法 TestButtonClicked 就会收到对应的回调,我们在此处处理按钮按下时执行的逻辑即可。

FReply FTestDetails::TestButtonClicked()
{
    UE_LOG(LogTemp, Log, TEXT(" Test button clicked. "));
    return FReply::Handled();
}

OnClicked 绑定的方法,需要以上述方式实现,返回一个 FReplay 类型的参数,以通知系统对此事件的处理结果。

3. 其他

系统中支持的回调事件有很多,如按压、松开等事件的回调,这里也不再赘述,读者自行跳转查阅即可。
Engine\Source\Runtime\Slate\Public\Widgets\Input\SButton.h
如下述几例:

    /** The text to display in this button, if no custom content is specified */
    SLATE_ATTRIBUTE( FText, Text )

    /** 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 )

二、输入框

1. 创建
    SNew(SHorizontalBox)
    +SHorizontalBox::Slot()
    .FillWidth(1.0f)
    [
        SNew(SEditableTextBox)
        .Text(LOCTEXT("EditableTextBox", "输入框"))
        .OnTextChanged(this, &FTestDetails::OnTextChanged)
    ]

UE 中自定义控件时可以使用 SEditableTextBox 来完成输入框的功能,这里与生成 Button 时类似,我们 New 了一个 SEditableTextBox 控件,并且指定了 OnTextChanged 时触发的方法 OnTextChanged。

2. 委托

当 UI 上输入框内的内容发生编辑变更时,此处我们指定的方法 OnTextChanged 就会收到对应的回调,我们在此处处理相应的逻辑即可。
联想时或许会较为轻易的找到这一委托,但是使用 Changed 收到的回调是文本框内容发生变更时的回调,因此这里笔者更推荐使用 OnTextCommitted,此事件只会在提交文本时调用(即用户按下回车,或文本框失去焦点时)。

void FTestDetails::OnTextChanged(const FText& Text)
{
    UE_LOG(LogTemp, Log, TEXT(" Text = %s"), *Text.ToString() );
}

段首的图片即是绑定到 OnTextChanged 事件的响应,这里笔者先删除了默认的 “输入框” 文字,而后输入了一些测试字符,可以看出,每次文字变更都会收到相应回调,因此更推荐使用 OnTextCommitted。

3. 其他

其他回调不再赘述,读者可自行查阅此处源码选择使用:
Engine\Source\Runtime\Slate\Public\Widgets\Input\SEditableTextBox.h

三、下拉框

1. 创建
    SNew(SHorizontalBox)
    +SHorizontalBox::Slot()
    .FillWidth(1.0f)
    [
        SNew(SComboBox<TSharedPtr<FString>>)
        .OptionsSource(FTestDetails::GetFruits())
        .OnSelectionChanged(this, &FTestDetails::OnSelectedFruitChanged)
        .OnGenerateWidget_Lambda([](TSharedPtr<FString> Value)->TSharedRef<SWidget>
        {
            return SNew(STextBlock).Text(FText::FromString(*Value)); // 下拉项
        })
        [
            SNew(STextBlock).Text(this, &FTestDetails::GetCurFruit) // 选中项
        ]
    ]

下拉框可以使用 SComboBox 或 SComboButton 来实现,这里以 SComboBox 为例,相交于前两例,稍微复杂了一些,首先我们需要指定 SComboBox 的模板参数,指定所使用的选项类型,其次还需要实现三个对应的委托才能满足其基础功能。

2. 委托
  • OptionsSource
    此委托用于绑定下拉列表下拉时需要显示的内容,需要定义一个返回指定模板参数的 TArray 指针,供返回下拉列表时使用其内容生成对应 UI 。

    TArray>* FTestDetails::GetFruits()
    {
        // TArray> Fruits;
        Fruits.Add(MakeShareable(new FString("Apple")));
        Fruits.Add(MakeShareable(new FString("Banana")));
        Fruits.Add(MakeShareable(new FString("Peach")));
        return &Fruits;
    }
  • OnGenerateWidget
    此委托需要指定用于生成表示选项的小部件的方法,用来生成对应下拉控件与选中控件。
    上述代码中以匿名函数方式进行了定义。

    FText FTestDetails::GetCurFruit() const
    {
        return this->SelectedFruit;
    }
  • OnSelectionChanged
    此委托将在下拉列表选项发生变更时触发,用于针对选中操作处理一些相关的逻辑。

    void FTestDetails::OnSelectedFruitChanged(TSharedPtr NewValue, ESelectInfo::Type Info)
    {
        this->SelectedFruit = FText::FromString(*NewValue);
        UE_LOG(LogTemp, Log, TEXT(" New fruits = %s"), **NewValue );
    }
3. 其他

其他回调不再赘述,读者可自行查阅此处源码选择使用:
Engine\Source\Runtime\Slate\Public\Widgets\Input\SComboBox.h
Engine\Source\Runtime\Slate\Public\Widgets\Input\SComboButton.h

四、勾选框

1. 创建
    SNew(SHorizontalBox)
    +SHorizontalBox::Slot()
    .FillWidth(1.0f)
    [
        SNew(SCheckBox)
        // .Style(FCoreStyle::Get(), "RadioButton")
        .IsChecked(this, &FTestDetails::GetAgree)
        .OnCheckStateChanged(this, &FTestDetails::AgreeChanged)
        [
            SNew(STextBlock).Text(LOCTEXT("Agree ...", "同意上述..."))
        ]
    ]

UE 提供了 SCheckBox 实现勾选功能,这里我们 New 了一个 SCheckBox 并指定了 IsChecked 与 OnCheckStateChanged 绑定的委托。注释行 “.Style(FCoreStyle::Get(), "RadioButton")” 开启后,可以指定勾选框样式为圆形,即通常理解的单选框。

2. 委托
  • IsChecked
    此方法用于检查勾选框目前是否处于选中状态,需要返回一个勾选类型的枚举变量

    ECheckBoxState FTestDetails::GetAgree() const
    {
        return this->bAgree ? ECheckBoxState::Checked : ECheckBoxState::Unchecked;
    }
  • OnCheckStateChanged
    此方法是当勾选框状态发生变更时的回调,入参为勾选后 勾选框的状态

    void FTestDetails::AgreeChanged(ECheckBoxState CheckBoxState)
    {
        bAgree = CheckBoxState == ECheckBoxState::Checked ? true : false;
        UE_LOG(LogTemp, Log, TEXT(" CheckBoxState = %d"), CheckBoxState );
    }
    
3. 其他

其他回调不再赘述,读者可自行查阅此处源码选择使用:
Engine\Source\Runtime\SlateCore\Public\Styling\SlateTypes.h

如堕五里雾中
最后更新于 2023-07-27