[C++] Creating widgets runtime

My problem occurs when I use the “NewObject” function to create my custom Widget, that is derived from UUserWidget.

Inside my custom class I have an UButton that I initialize in “OnWidgetRebuilt”. But that UButton remains nullptr after I create my widget with “NewObject”. Probably because “OnWidgetRebuilt” does not get called.

My question is as follows:
What virtual function should I override in my “custom widget” class, so that when I create a “custom widget” the overriden function is called. (And I can initialize other Widgets in that function).

This is where my UButton get initialized:

void UMInventorySlot::OnWidgetRebuilt()
{
	slotButton = Cast<UButton>(WidgetTree->RootWidget = WidgetTree->ConstructWidget<UButton>(UButton::StaticClass(), FName("inventorySlot")));

	// Delegates
	slotButton->OnPressed.AddDynamic(this, &UMInventorySlot::OnPressedEnterDel);
	slotButton->OnReleased.AddDynamic(this, &UMInventorySlot::OnPressedExitDel);

	slotButton->OnHovered.AddDynamic(this, &UMInventorySlot::OnHoverEnterDel);
	slotButton->OnUnhovered.AddDynamic(this, &UMInventorySlot::OnHoverExitDel);
	// ~Delegates

	Super::OnWidgetRebuilt();
}

If you are not aware yet, UMG is just front end of Slate, UI system designed originaly for editor, but it can be used in games, problem is it was not designed to cooperate with Blueprint (most impotently it’s classes are outside of UObject class), thats why UMG was made to wrap Slate functions

UMG widgets (UWidget) are just UObject shells for already exiting Slate widgets, and because of this UWidget can contain whole composition of Slate widgets. Slate widgets are also a lot easier to operate in C++. So insted of making UUserWidget and reuse UMG widgets, you should use UWidget and incorporate Slate widget in it, trust me you will find it a lot easier to work with in C++. In UWidget you override this function

And you return slate widget definition and that it, your function would look like this:

TSharedRef < SWidget > RebuildWidget() {

       return SNew(SButton)
                  .OnPressed(this, &UMInventorySlot::OnPressedEnterDel)
                  .OnReleased(this, &UMInventorySlot::OnPressedExitDel)
                  .OnHovered(this, &UMInventorySlot::OnHoverEnterDel)
                  .OnUnhovered(this, &UMInventorySlot::OnHoverExitDel)
                  .Content()
                  [
                         //You put here SNew with widget that will be inside Button
                  ];
          
}

only one more thing you need to do is to override this function:

It is called when widget proprieties are changed and you should set changed properties to widget settings and oyu can get Slate widget from here:

Ofcorse you need to learn about slate, there docs here with examples. Sicne you work with UMG you should be aware of how it’s concept work as UMG inherets it’s workings:

Look on SWidget API refrence to see list of all widgets, you should already be familiar with them as they already used in UMG

each widget class have nested FArgument class with list of all arguments oyu can use in SNew and SAssignNew, here example from SButton

One of big benifuits of using Slate direcly to create custom widget is fact that Slate widgets are not visible by UMG and in UMG composition of Slate widgets feel like a truly single widget. There also more widgets in Slate (just watch out that they aren’t part of editor code) and not all of them been added in to UMG, so there a lot more possibilities.

Thank you. This is a great answer!

Also could you please tell me how I can avoid hard-coding the content of the SWidget?

Forward properties of content to your UMG widget. what kind of content you want to put in it? How it suppose to behave and how dynamic it is?

So I want to create an UMG widget that has a number of custom UMG widgets inside it and that number is known run-time