How to dynamically create a UWidget instance and add it to a UCanvasPanel in C++?

I have a class derived from UWidget, defined as follows: class UMGSPLINE_API UDrawWidget final : public UWidget. I want to dynamically create an instance of this UWidget during runtime, but I encountered a compilation error when trying to use CreateWidget. Are there any other ways to create a UWidget in C++? Below is my code:

UDrawWidget* pDrawLine = CreateWidget<UDrawWidget>(GetWorld());
pDrawLine->SetSplineMaterial(pDotLineMaterial);
pDrawLine->RemoveAllSplinePoint(true);
m_pDrawLinePanel->AddChild(pDrawLine);
m_bTopTrackPanel ? Cast<UCanvasPanelSlot>(pDrawLine->Slot)->SetSize(FVector2D(230.0f, 400.0f)) : Cast<UCanvasPanelSlot>(pDrawLine->Slot)->SetSize(FVector2D(300.0f, 200.0f));
m_arrCoordYWidget.Add(pDrawLine);

pDrawLine = CreateWidget<UDrawWidget>(GetWorld());
pDrawLine->SetSplineMaterial(pWhiteLineMaterial);
pDrawLine->RemoveAllSplinePoint(true);
m_pDrawLinePanel->AddChild(pDrawLine);
m_bTopTrackPanel ? Cast<UCanvasPanelSlot>(pDrawLine->Slot)->SetSize(FVector2D(230.0f, 400.0f)) : Cast<UCanvasPanelSlot>(pDrawLine->Slot)->SetSize(FVector2D(300.0f, 200.0f));
m_arrCoordXWidget.Add(pDrawLine);

You need to pass in who’s the owner of the created widget (just like in BP)

add needed import:

#include "Kismet/GameplayStatics.h"

Then you can use this

if (APlayerController* PlayerController = UGameplayStatics::GetPlayerController(GetWorld(),0)) 
{
	UDrawWidget* DWidget = CreateWidget<UDrawWidget>(PlayerController, UDrawWidget::StaticClass());
}

Or if you want to push in a specific bp implementation of the widget then try

if (APlayerController* PlayerController = UGameplayStatics::GetPlayerController(GetWorld(),0)) 
{
	if (DrawWidgetClass != nullptr) {
		if (UDrawWidget* DWidget = CreateWidget<UDrawWidget>(PlayerController, DrawWidgetClass))
		{
			DWidget->AddToViewport();
		}
	}
}

And just add an exposed uproperty in the header

UPROPERTY(BlueprintReadWrite, EditAnywhere)
TSubclassOf<class UDrawWidget> DrawWidgetClass;

Also make sure to make widgets during begin play or after (the world needs to exist, can't be done in the constructor)
1 Like