[UE4]UMG widget构造初始化函数中获取其内部组件

发表于2016-05-31
评论1 4.1k浏览

原文作者:@玄冬Wong

      目的:在自定义的Widget初始化完毕后,获取其内部的button、combo等UMG组件的C++指针。

      这里我们新建了一个C++类,LoginWidget,继承自UserWidget,然后新建了一个Widget蓝图LoginWidgetBP,继承自LoginWidget C++ class。我们想在这个LoginWidgetBP蓝图被实例化之后,获取这个UI蓝图内的各个UI组件。

 

具体实现:

     LoginWidget.h

    Cpp代码  收藏代码
1
2
3
4
bool Initialize() override; 
UComboBoxString* ComboServer; 
UEditableTextBox* TxtBoxAccount; 
UEditableTextBox* TxtBoxPwd; 

     假设我自己的Widget叫LoginWidget,继承自:UserWidget。

Cpp代码  收藏代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1.ULoginWidget::ULoginWidget(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) 
2.{ 
3.    ComboServer = NULL; 
4.    TxtBoxAccount = NULL; 
5.    TxtBoxPwd = NULL; 
6.} 
7. 
8.bool ULoginWidget::Initialize() 
9.{ 
10.    if (!Super::Initialize()) 
11.    { 
12.        return false
13.    } 
14.     
15.    if (UComboBoxString* combo = Cast(GetWidgetFromName("ComboServer"))) 
16.    { 
17.        ComboServer = combo; 
18.    } 
19.    if (UEditableTextBox* txtbox = Cast(GetWidgetFromName("TxtBoxAccount"))) 
20.    { 
21.        TxtBoxAccount = txtbox; 
22.        TxtBoxAccount->SetKeyboardFocus(); 
23.    } 
24.    if (UEditableTextBox* txtbox = Cast(GetWidgetFromName("TxtBoxPwd"))) 
25.    { 
26.        TxtBoxPwd = txtbox; 
27.    } 
28. 
29.    return true
30.} 

其中,这个判断是必须的,否则出现空指针异常:

Cpp代码  收藏代码
1
2
3
4
if (!Super::Initialize()) 
    return false
       ComboServer、TxtBoxAccount、TxtBoxPwd三个字符串分别是widget组件ID。另外也不用担心各个组件的层级关系(比如,Image A是Button的子节点),widget蓝图中的所有组件存放在UserWidget中的一个map当中。

 

补充:

      父类还有一个函数:

      Cpp代码  收藏代码
1
virtual void CustomNativeInitilize() {}

        如果当前实例化的UI不是widget蓝图,而是一个C++ class,在触发Initialize()之后,还会继续触发CustomNativeInitilize(),否则只触发Initialize(),参见UserWidget.cpp:
Cpp代码  收藏代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
bool UUserWidget::Initialize() 
   // If it's not initialized initialize it, as long as it's not the CDO, we never initialize the CDO. 
    if ( !bInitialized && !HasAnyFlags(RF_ClassDefaultObject) ) 
    
        bInitialized = true
  
       // Only do this if this widget is of a blueprint class 
        UWidgetBlueprintGeneratedClass* BGClass = Cast(GetClass()); 
       if ( BGClass != nullptr ) 
        
            BGClass->InitializeWidget(this); 
        
        else 
        
            CustomNativeInitilize(); 
        



如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引