Using pure C++ UUserWidget inside of another BP widget in UMG editor

How to create UUserWidget and populate it with widgets in C++?
For example, create UUserWidget, then create and add Text Box to it

I’ve tried to WidgetTree->CosntructWidget and assigning it to WidgetTree->RootWidget inside NativeOnInitialized/NativeConstruct/NativePreConstruct, like so:

// .h
UCLASS()
class PURECPPWIDGET_API UMyUserWidget : public UUserWidget
{
	GENERATED_BODY()

public:
	UCanvasPanel* CanvasPanel;

private:
	void NativeOnInitialized() override;
	void NativeConstruct() override;
	void NativePreConstruct() override;

	void CreateWidgets();
};

// .cpp
void UMyUserWidget::NativeOnInitialized()
{
	UE_LOG(LogTemp, Warning, TEXT("UMyUserWidget::NativeOnInitialized before"));
	Super::NativeOnInitialized();

	CreateWidgets();
}

void UMyUserWidget::NativeConstruct()
{
	UE_LOG(LogTemp, Warning, TEXT("UMyUserWidget::NativeCosntruct"));
	Super::NativeConstruct();
}

void UMyUserWidget::NativePreConstruct()
{
	UE_LOG(LogTemp, Warning, TEXT("UMyUserWidget::NativePreConstruct"));
	Super::NativePreConstruct();
}

void UMyUserWidget::CreateWidgets()
{
	UE_LOG(LogTemp, Warning, TEXT("UMyUserWidget::CreateWidgets before"));

	CanvasPanel = WidgetTree->ConstructWidget<UCanvasPanel>(UCanvasPanel::StaticClass());
	if (!CanvasPanel)
		return;

	auto textBlock = WidgetTree->ConstructWidget<UTextBlock>(UTextBlock::StaticClass());
	textBlock->SetText(FText::FromString("Hello World!"));
	CanvasPanel->AddChildToCanvas(textBlock);

        // WidgetTree->RootWidget = textBlock;
	WidgetTree->RootWidget = CanvasPanel;

	UE_LOG(LogTemp, Warning, TEXT("UMyUserWidget::CreateWidgets after"));
}

But when I add My User Widget in UMG editor, nothing is visible

I think a similar question has already been asked and answered in this thread.

Yeah, and I’ve tried the solution from there but it doesn’t work Create widget in pure C++ - #41 by isaac4096

I remember trying to do this a while back and gave up. The only thing I’ve seen since is trying to tell the editor that the widget hierarchy has been modified. You’ll need to call Modify() on every asset you’ve added and every parent in the hierarchy.

    UWidgetBlueprintGeneratedClass* wbpClass = Cast<UWidgetBlueprintGeneratedClass>(WidgetTree->RootWidget->GetClass());
    UWidgetBlueprint* asset = Cast<UWidgetBlueprint>(wbpClass->GetPackage()->FindAssetInPackage());

    asset->Modify();

    // Tell editor that blueprint has changed.
    FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(asset);

I have no clue if this will work but thought I’d mention it as it’s easy enough to try.

1 Like

I won’t lie, I should have checked that thread before suggesting it, as it doesn’t even have a proper answer to the OP’s problem. I just saw a post with 13 likes and was convinced it should work.
I found a site that seems to do what you’re asking. I tested it myself, and it seems to work (sort of).

1 Like

The whole point is not to use BindWidget.

Quoting the docs:

From the docs here:

Debatable. I’ve been a programmer for over 40 years. I’m not a fan of this blanket strategy. But this is another topic.

1 Like

Yeah, this

It’s a really good thing to use BindWidget when there’s a need to change anything in UMG editor

But when you just want to have a wrapper for a widget (UTextBlock in my case), then you really don’t want those extra steps with BindWidget