智慧 + 毅力 = 无所不能

正确性、健壮性、可靠性、效率、易用性、可读性、可复用性、兼容性、可移植性...
随笔 - 991, 文章 - 0, 评论 - 27, 阅读 - 341万

导航

< 2025年3月 >
23 24 25 26 27 28 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 2 3 4 5

转自:http://aigo.iteye.com/blog/2296218

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

 

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

 

具体实现:

LoginWidget.h

bool Initialize() override;  
UComboBoxString* ComboServer;  
UEditableTextBox* TxtBoxAccount;  
UEditableTextBox* TxtBoxPwd;  

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

Cpp代码  收藏代码
复制代码
ULoginWidget::ULoginWidget(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)  
{  
    ComboServer = NULL;  
    TxtBoxAccount = NULL;  
    TxtBoxPwd = NULL;  
}  
  
bool ULoginWidget::Initialize()  
{  
    if (!Super::Initialize())  
    {  
        return false;  
    }  
      
    if (UComboBoxString* combo = Cast<UComboBoxString>(GetWidgetFromName("ComboServer")))  
    {  
        ComboServer = combo;  
    }  
    if (UEditableTextBox* txtbox = Cast<UEditableTextBox>(GetWidgetFromName("TxtBoxAccount")))  
    {  
        TxtBoxAccount = txtbox;  
        TxtBoxAccount->SetKeyboardFocus();  
    }  
    if (UEditableTextBox* txtbox = Cast<UEditableTextBox>(GetWidgetFromName("TxtBoxPwd")))  
    {  
        TxtBoxPwd = txtbox;  
    }  
  
    return true;  
}  
复制代码

 

 

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

if (!Super::Initialize())  
{  
    return false;  
}  

 

 ComboServer、TxtBoxAccount、TxtBoxPwd三个字符串分别是widget组件ID。另外也不用担心各个组件的层级关系(比如,Image A是Button的子节点),widget蓝图中的所有组件存放在UserWidget中的一个map当中。

 

补充:

父类还有一个函数:

virtual void CustomNativeInitilize() {}  

 如果当前实例化的UI不是widget蓝图,而是一个C++ class,在触发Initialize()之后,还会继续触发CustomNativeInitilize(),否则只触发Initialize(),参见UserWidget.cpp:

复制代码
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<UWidgetBlueprintGeneratedClass>(GetClass());  
        if ( BGClass != nullptr )  
        {  
            BGClass->InitializeWidget(this);  
        }  
        else  
        {  
            CustomNativeInitilize();  
        }  
    }
}
复制代码

 

C++UI组件Slate教程

官方文档:

Slate, Hello

https://wiki.unrealengine.com/Slate,_Hello

Slate Widget Examples

https://docs.unrealengine.com/latest/INT/Programming/Slate/Widgets/

Slate Tutorial

https://forums.unrealengine.com/showthread.php?822-Slate-Tutorial

(评论功能已被禁用)
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述
历史上的今天:
2010-10-25 Web服务
点击右上角即可分享
微信分享提示