Reputation: 3563
I want to call function, which changes the text inside the widget.
There is a virtual
function NativeConstruct
, which calls automatically. And it changes text of widget, but I need to call function F1
and send a text to it, which I want to display. But when I call it, the variable Name
is nullptr
. And by some reason, it is not nullptr
, when program call NativeConstruct
.
Name
is my text variable, which I want to changedialogBottom
is the name of widget with this variableEdited
UAccessWidgetFromCpp* AccessWidgetFromCpp
= CreateWidget<UAccessWidgetFromCpp>(
GetWorld()->GetFirstPlayerController(), UAccessWidgetFromCpp::StaticClass()
);
if (AccessWidgetFromCpp)
{
AccessWidgetFromCpp->F1("222");
widgetDialogBottomInstance->AddToViewport();
}
UCLASS()
class HOME_API UAccessWidgetFromCpp : public UUserWidget
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UTextBlock* Name = nullptr;
UFUNCTION()
void F1(FString text);
};
void UAccessWidgetFromCpp::F1(FString text)
{
if (auto widget = dynamic_cast<UTextBlock*>(GetWidgetFromName(TEXT("Name"))))
{
Name = widget;
Name->SetText(FText::FromString(text));
}
}
Upvotes: 3
Views: 6040
Reputation: 32982
Your UPROPERTY
the Name
has not initialized to nullptr
in the beginning. Therefore, it could contain any garbage value inside it.
Initialize it to nullptr
in the class definition or in the constructor of UAccessWidgetFromCpp
(if any). For instance, this will fix the issue
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UTextBlock* Name = nullptr;
// ^^^^^^^^^^
Regarding the new update:
First of all, you should avoid using c-style casting in C++. Secondly, the function GetWidgetFromName
returns, uobject widget corresponding to a given name. Therefore you should be sure about having one with "Name
".
Otherwise, make your code safe by double-checking the nullptr
scenarios.
if(auto widget = dynamic_cast<UTextBlock*>(GetWidgetFromName(TEXT("Name"))))
{
Name = widget;
Name->SetText(FText::FromString(text));
}
Even now you do not reach the line Name->SetText(FText::FromString(text));
means either you have no widget called "Name
" or it is not possible to cast the UWidget*
to a UTextBlock*
. You might need a redesign of how to do this.
Upvotes: 5
Reputation: 3829
Remember to practise defensive programming! Initialize ptr values to nullptr - never assume variables are initialised in C++. The code if(Name)
does not check if a UObject is valid, it just checks that there is some value in the variable - and that value will be some garbage value if the variable has not been initialised.
Furthermore, I'd recommend checking variables (that might possibly be null) immediately prior to dereferencing them.
GetWidgetFromName
returns the uobject widget corresponding to a given name
If there is no uobject widget corresponding to the given name (eg. due to a typo in the supplied text or some code logic error), the UE4 docs are not explicit and I haven't tested it personally, but I would assume that nullptr
will be returned. If so, the null return would happen after your if(Name)
check yielding a nullptr dereference.
ie.
void UAccessWidgetFromCpp::F1(FString text)
{
if (Name)
{
Name = (UTextBlock*)GetWidgetFromName(TEXT("Name"));
// if there is no Widget with name "Name" then the variable Name
// may now be null even if it wasn't at the if check earlier
Name->SetText(FText::FromString(text));
}
}
Hope that clarifies (naming the widget variable "Name" certainly doesn't help).
Upvotes: 2