How do I include a widget/blueprint in a widget/C++?

I want to use a widget made in blueprint in another widget made in C++.

Basically because the one that is made in blueprint is just an interface/template but with style.

So this is my widget made in blueprint.

This is my code in C++

And i want to use UI_TextBlock instead of UTextBlock

4

But I can’t include the class like I normally would in C++

5

Is it possible to do it? How to do it?
Thank you so much!!


UPDATE:


I tried the solutions offered to me in the answers. However I have not been able to get it to work. I think it’s my fault. I should have given more information about my custom TextBlock class. I think that is why it is more complex than I imagined.

This is the class:

I made a blueprint derived from this class and it worked fine.

I want to be able to make multiple instances of this class in the same way as bluprints but using C++.

I think that when instantiating the object the “constructor” is not executed.
6

I tried to instantiate all the objects of the class by in a function outside the constructor. but this didn’t work either.

I’m just trying to do the same thing I’ve done before with bluprints but in C++. Use a simple UserWidget as a component so that I can reuse it in another more complex UserWidget (Simple Composition).

I’ve put the classes and the implementation in these two header files if you want to take a look. Maybe so you can see what I’m doing wrong.

CTextBlock.h (6.8 KB)

LobbyWidget.h (2.4 KB)

Thank you very much for your help.

You can’t use bluprint created classes in C++, but you can create new C++ class from UUserWidget (name f.e. UMyTextBlock), create a special field of UTextBlock (public, protected or private - as you wish):

UPROPERTY(meta=(BindWidget))
UTextBlock* TextBlock; // or whatever name TextBlock in your BP has

and reparent your BP widget to new C++ class.
After what, whre is 2 possible ways:

  • at every widget you want to use UMyTextBlock staticly (not to spawn at runtime) use
UPROPERTY(meta=(BindWidget))
UMyTextBlock* TextBlock; // or whatever name TextBlock in your BP has

and simply put BP delivered from UMyTextBlock widget in designer window as usual TextBlock.

  • To spawn BP widget (inherited from UMyTextBlock) at runtime, create a field:
UPROPERTY(EditDefaultsOnly)
TSubclassOf<UMyTextBlock> MyTextBlockClass;

and spawn in a way of spawning default UTextBlock but passing MyTextBlockClass as a class to spawn. This is a modificated example of your code:

for(APlayerState* playerState : gameState->PlayerArray){
    UMyTextBlock* textBlock = WidgetTree->ConstructWidget<UMyTextBlock>(MyTextBlockClass); // WidgetTree->ConstructWidget is like NewObject, but for widgets. 
    FText InText = FText::FromString(playerState->GetPlayerName());
    textBlock->TextBlock->SetText(InText); // if you made TextBlock field in UMyTextBlock private or protected, use setters
    playersVerticalBox->AddChild(textBlock);
}
1 Like

if you want using UI_TextBlock instead of UTextBlock in c++
in constructor of ULobbyWidget add :

static ConstructorHelpers::FClassFinder<UTextBlock> TextBlockWidgetObj (TEXT ("your UI_TextBlock ref path"));
    if (TextBlockWidgetObj .Succeeded ()) {
        TSubclassOf<UTextBlock>TextBlockWidgetObjClass = TextBlockWidgetObj .Class;
    }

in your create widget function using TextBlockWidgetObjClass instead UTextBlock::StaticClass()

1 Like

Hi

I am convinced that your answer is the way that best suits what I need. However I think my class is too complex. Or it is not well designed for what I want to do with it. I have added additional information at the end of my question (and source code). Maybe if you take a look at it you can tell me it’s badly done.

Thank you very much for your help.
Really very much appreciated.

Hello

Thank you very much for your reply. I think it is a very interesting solution and can be very useful. In fact it is the exact answer to my original question.

However, I think that in this specific case it won’t work, since my class is not really derived from UTextBlock.

It’s my fault, I should have given more information about the class when asking the question.

In fact I have expanded the information on that at the end of my original question now.

Anyway I want to thank you. I am sure that I will use this method that you have taught me.

I really appreciate your help a lot.

I look at your code and I think you just didn’t understand what I mean. Let me show you an example from my project:
I have a custom ProgressBar class called WeaponStatusProgressBar. This class is inherited from UFancyProgressBar:
FancyProgressBar.h

UCLASS()
class FLIGHTPROJECT_API UFancyProgressBar : public UUserWidget
{
	GENERATED_BODY()

public:

	UFUNCTION(BlueprintCallable)
	void SetProgress(float Alpha); // the only reason of making this method is setting Alpha value to ProgressBar and keep ProgressBar protected

protected:

	UPROPERTY(meta=(BindWidget))
	UProgressBar* ProgressBar;
	
};

FancyProgressBar.cpp (yes, this is the full code)

#include "UI/FancyProgressBar.h"

void UFancyProgressBar::SetProgress(float Alpha)
{
	ProgressBar->SetPercent(Alpha);
}

and blueprint WeaponStatusProgressBar inherited from UFancyProgressBar (no logic, just visual):

I have a weapon widget called BP_WeaponWidget, there I want to use my blueprint BP_FancyProgressBar as a reload widget. Problem is that all BP_WeaponWidget logic written in C++ in UWeaponStatusWidgetBase class. So, I created a UPROPERTY with class of UFancyProgressBar:

protected:

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
	TSubclassOf<UFancyProgressBar> ProgressBarClass;

In widget logic I dynamicly spawn as much instances of WeaponStatusProgressBar as I want by using this code:

	auto NewBar = WidgetTree->ConstructWidget<UFancyProgressBar>(ProgressBarClass); // spawn a widget of class ProgressBarClass and return a pointer as UFancyProgressBar
	ProjectilesBox->AddChildToHorizontalBox(NewBar); // add to parent (show on screen)
	return NewBar;

And, in UWeaponStatusWidgetBase inherited BP class I simply set a class of my WeaponStatusProgressBar as a parameter:
image
And that’s all. If you need a static widget, just use

UPROPERTY(meta=(BindWidget))
UYourWidget* YourWidget;

and in BP put your widget as ordinary Canvas or Text components.

1 Like

Yes!! this works perfect!!
You have saved me from madness!!
I spent many hours trying to make this work.
Thank you very much, I really appreciate your help!! :heart: :heart: :heart: :heart: