最近使用Slate写了一个UE内的编辑工具,刚好遇到了制作对话框的需求。因此,记录一下实现的方法并分享出来。
目录
分析窗口的构成和功能
构成
功能
编写Slate
模态对话框
分析窗口的构成和功能
构成
首先我们要分析要制作的窗口,包含哪些内容。以下图对话框为例。

此对话框,包含的元素有标题栏、输入框、确认按钮和取消按钮。
让我们来逐一分析这些元素用了哪些Slate组件:
标题栏 - SWindow
输入框 - SEditableTextBox
确认按钮、取消按钮 - SButton
功能
这个窗口的功能,不但要记住用户到底是点了确认还是取消,还要记住用户在输入框内输入的内容。因此我们需要保存这些对象的指针,方便对话框运行完毕后取得我们想要的内容。
分析完毕后,我们就可以使用Slate进行编写了。
编写Slate
首先是对话框整体,SWindow:
TSharedPtr<SWindow> MyDialog = SNew(SWindow)
.Title(Title) // 窗口标题名
.SizingRule(ESizingRule::Autosized) // 根据内容大小设定尺寸
.SupportsMinimize(false) // 隐藏最小化按钮
.SupportsMaximize(false); // 隐藏最大化按钮
然后是内容输入框,使用SEditableBox,并且在对话框运行完后获取输入的内容:
TSharedPtr<SEditableTextBox> TextBox = SNew(SEditableTextBox);
... 对话框运行过程 ...
// 窗口运行结束后,获取输入框的内容
InputString = TextBox->GetText().ToString();
最后编写确认按钮与取消按钮,这两个按钮需要做到两件事:
1. 记录用户按下了自身
2. 用户按下自身后关闭对话框
TSharedPtr<SButton> OkBtn = SNew(SButton)
.VAlign(VAlign_Center)
.HAlign(HAlign_Center)
[
SNew(STextBlock)
.Text(FText::FromString("OK"))
];
TSharedPtr<SButton> CancelBtn = SNew(SButton)
.VAlign(VAlign_Center)
.HAlign(HAlign_Center)
[
SNew(STextBlock)
.Text(FText::FromString("Cancel"))
];
再为按钮添加点击事件响应
bool bResult = false;
OkBtn->SetOnClicked(
FOnClicked::CreateLambda([&]()->FReply
{
bResult = true;
MyDialog->RequestDestroyWindow();
return FReply::Handled();
})
);
OkBtn->SetOnClicked(
FOnClicked::CreateLambda([&]()->FReply
{
bResult = false;
MyDialog->RequestDestroyWindow();
return FReply::Handled();
})
);
当对话框运行完毕后,我们可以根据bResult获知用户按下了确认按钮还是取消按钮。再根据TextBox->GetText().ToString()拿到输入框的内容。
最后,我们把创建的各个Slate组件合并到一起,使用MyDialog的SetContent函数,将输入框与按钮加入到布局中。
MyDialog->SetContent(
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.Padding(5,8,5,5)
[
TextBox.ToSharedRef()
]
+ SVerticalBox::Slot()
.Padding(5, 5, 5, 5)
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.Padding(10,0)
[
OkBtn.ToSharedRef()
]
+ SHorizontalBox::Slot()
.Padding(10, 0)
[
CancelBtn.ToSharedRef()
]
]
);
模态对话框
一般来说,我们要做的对话框是模态的,即是指在用户想要对对话框以外的应用程序进行操作时,必须首先对该对话框进行响应。因此我们要用到的核心代码是:
FSlateApplication::Get().AddModalWindow(MyDialog, DialogParent);
该函数可以使得我们传入的SWindow类型的MyDialog成为模态窗口,并阻塞用户对UE的其他窗口进行操作。