最近使用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的其他視窗進行操作。