How can I create a Panel and add it to the viewport via C++? Or at least add a CanvasPanel as a child of a UUserWidget?
…Bump?
Hello.
For creating UserWidgets you can use one of templated functions from UserWidget.h (see here - github acc linked to ue4 required).
You use them like:
// Player controller for which the widget is meant to be created.
// Needs to be populated somehow.
APlayerController* OwningPC;
// Widget creation
UUserWidget* Widget = CreateWidget<UYourUserWidgetClass>(OwningPC, UYourUserWidgetClass::StaticClass());
// Adding widget to screen
Widget->AddToViewport();
To create, a widget that doesn’t derive from UUserWidget, you have to use NewObject function instead.
Example:
// An object within which newly created widget is meant to be in.
// It can be just a widget to which you want to add that new widget.
// Needs to be populated somehow.
UObject* Outer;
UCanvasPanel* CanvasPanel = Cast<UCanvasPanel>(InOuter);
// Widget creation
UTextBlock* TextBlock = NewObject<UTextBlock>(Outer, UTextBlock::StaticClass());
// Adding widget to canvas panel
CanvasPanel->AddChild(TextBlock);
// Created widget is emptier, than the one you create in UMG designer.
// So to actually see it, you'll have to set it up.
TextBlock->SetText(FText::FromString(TEXT("Some text")));
I know for sure, that it does work for runtime widget creation. Although it works for creating widgets in UMG designer mode, you cannot interact with widgets created that way, because such widget isn’t added to widget hierarchy (window on the left side of the screen, between animations and pallete). You can modify it if you have pointer to it, tho.
As a side note: one/couple of NewObject overloads accepts object that acts as template. When that’s used, the function pretty much duplicates most/all data from template object and sets that up on newly created object.
Edit:
To add a UWidget to a UUserWidget, you’d have to provide a reference to any UPanelWidget that is within that UserWidget. I don’t know if there’s a way to add that widget directly to UserWidget (and skip the UPanelWidget thing).
I haven’t tried that, but if you really need it, you could check out WidgetTree property of UUserWidget and play around with that. Maybe you’d have some luck with it.
Edit2:
One more thing about adding widget to Widget Blueprint in UMG designer mode. A widget created that way, would be removed during compilation of Widget Blueprint to which that widget was added. So you’d have to re-add that (UWidget::SynchronizeProperties function is perfect for that).
Additionally, you might have to propagate designer flags to created widgets if these derive from UUserWidget. See UUserWidget::SetDesignerFlags. Designer flags are editor-only thing, so you’d have to wrap that with #if WITH_EDITOR.
Cheers.
Can you explain with a code the second Edit? please.
@Atheist91 Is the hierarchy still not available in the designer? Trying to see if I can setup a plugin programmatically to save space in repo.