Create Widget and display it pure c++

Hi,
I’m trying to show on my viewport n widgets having an image attached to it, n being the number of targets my imitation/ folder so I created an actor and here’s the beginPlay Method of it :

for (const FString& Target : mTargets) {

  // Spawn the widget
  UImitationWidget* NewTargetWidget = CreateWidget<UImitationWidget>(GetWorld(), ImitationWidgetClass);

  //create the image so it's not null
  NewTargetWidget->TargetImage = NewObject<UImage>();

  NewTargetWidget->SetTargetName(Target);
  //move the widget to the right
  NewTargetWidget->AddToViewport();
  NewTargetWidget->SetPositionInViewport(FVector2D(posx, 0));
  posx += 400;

  UE_LOG(LogTemp, Warning, TEXT("Spawning widget for target: %s"), *Target);
}

Here’s the widget I’m creating :

UImitationWidget::UImitationWidget(const FObjectInitializer& ObjectInitializer)
  : Super(ObjectInitializer)
{
  LoadedTexture = nullptr;
  TargetName = "";
  bIsImageLoaded = false;
}

void UImitationWidget::NativeConstruct()
{
  Super::NativeConstruct();

  // Load the image for the target
  if (bIsImageLoaded)
  {
    LoadImageForTarget();
  }
}

void UImitationWidget::SetTargetName(const FString& NewTargetName)
{
  //log target name
  UE_LOG(LogTemp, Warning, TEXT("NewTargetName: %s"), *NewTargetName);
  TargetName = NewTargetName;
  bIsImageLoaded = true;
}

void UImitationWidget::LoadImageForTarget()
{
  FString TexturePath = FString::Printf(TEXT("/Game/imitation/images/%s.%s"), *TargetName, *TargetName);
  //log the path
   UE_LOG(LogTemp, Warning, TEXT("TexturePath: %s"), *TexturePath);

   // Load the texture asset
   LoadedTexture = LoadObject<UTexture2D>(nullptr, *TexturePath);

  if (LoadedTexture == nullptr)
    UE_LOG(LogTemp, Error, TEXT("Failed to load texture for target: %s"), *TargetName);

  TargetImage->SetBrushFromTexture(LoadedTexture);
}```
Header for it : 
```c++
UCLASS()
class MYPROJECT2_API UImitationWidget : public UUserWidget
{
	GENERATED_BODY()
public:
  UImitationWidget(const FObjectInitializer& ObjectInitializer);

  void NativeConstruct() override;

  // Function to set the target name
  UFUNCTION(BlueprintCallable, Category = "Target Widget")
  void SetTargetName(const FString& NewTargetName);

  // Function to load the image for the target
  UFUNCTION(BlueprintCallable, Category = "Target Widget")
  void LoadImageForTarget() const;

  UPROPERTY()
  UImage* BlackSquareImage;

  UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Target Widget", meta = (AllowPrivateAccess = "true"))
  FString TargetName;

  // Variable to hold the loaded texture
  UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Target Widget", meta = (AllowPrivateAccess = "true"))
  UTexture2D* LoadedTexture;
};

I created a widget Blueprint linked to it and create it in my HUD :

The widget is correctly created but it seems that I can’t really change its position its size in my for loop so they stack at one place

I am not 100% sure what you are asking, but where is posx saved? Maybe it is geting initialised to 0 each time.

posx is initialised in the constructor since it’s a member variable :

That UImitationWidget inherits from which class??

It’s stated in the code

class MYPROJECT2_API UImitationWidget : public UUserWidget

so it inherits from UUserWidget

I made everything in Blueprint and It works fine now :slight_smile:

I just use the c++ file to set the Image’s texture depending of the target name

So what I do if your class inherits from UUserWidget if this. I create a function in the class that will create the widget that use the tag BlueprintImplementableEvent. This, allows me to call this function from the C++ class but define it in blueprints. The definition in blueprint is the traditional node Create Widget, where you can use a Widget Blueprint.


#pragma once

#include "CoreMinimal.h"
#include "Components/BaseComponent.h"
#include "Login.generated.h"

class UBackgroundBlur;

 */
UCLASS()
class UIMODULE_API UYourWidget: public UUserWidget
{
	GENERATED_BODY()

public:

	UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
	UBackgroundBlur* B_Background;


	UFUNCTION(BlueprintImplementableEvent, Category = "Config|Implementable")
	void CreateWidget();

	
};

Once the widget is created using the BlueprintImplementableEvent, I save it as variable in my class to do what i want to do like this for example.

CreateWidget();

if (WidgetBlueprintVariable)
{
	WidgetBlueprintVariable->AddToViewport();
	...
}