UWidget::SynchronizeProperties() 未在编辑器中调用 属性 更改
UWidget::SynchronizeProperties() is not being called on in editor property change
每次从小部件编辑器更改枚举变量 属性 时,我都必须更改子列表。
None 到目前为止我尝试过的功能似乎都有效(virtual void OnEndEditByDesigner(); virtual void PostEditChangeProperty(struct FPropertyChangedEvent & PropertyChangedEvent)).
SynchronizeProperties 文档指出
It can also be called by the editor to update modified state, so ensure all initialization to a widgets properties are performed here, or the property and visual state may become unsynced.
所以我不完全确定它是 use/overwrite 的正确函数(因为编辑器只能“可以”调用它来更新修改后的状态,不会在 属性编辑编辑)
下面是一些示例代码,展示了到目前为止我一直在尝试做的事情。
示例代码:
SampleButton.h
/* Includes */
#include "CoreMinimal.h"
#include "UObject/Object.h"
#include "Components/Button.h"
#include "Components/Image.h"
#include "Components/CanvasPanel.h"
#include "Components/ButtonSlot.h"
#include "Widgets/SOverlay.h"
#include "Components/Overlay.h"
#include "Components/TextBlock.h"
#include "Styling/SlateBrush.h"
#include "UUIW_MasterButton.generated.h"
//
UENUM(BlueprintType)
enum class EContentType : uint8
{
WithIcon,
WithText,
}
class SAMPLE_API SampleButton : public UButton
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintSetter=SetType, meta = (MakeEditWidget = ""))
EContentType ContentType = EContentType::WithIcon;
UPROPERTY(meta = (EditCondition = "ContentType == EContentType::WithIcon || ContentType == EContentType::WithTextAndIcon", EditConditionHides))
UImage* Icon;
UPROPERTY(meta = (EditCondition = "ContentType == EContentType::WithText || ContentType == EContentType::WithTextAndIcon", EditConditionHides))
UTextBlock* TextBlock;
protected:
virtual TSharedRef<SWidget> RebuildWidget() override;
UOverlay* Overlay;
virtual void SynchronizeProperties();
}
SampleButton.cpp
#include "UI/SampleButton.h"
TSharedRef<SWidget> SampleButton::RebuildWidget()
{
Overlay = NewObject<UOverlay>();
auto ButtonRef = Super::RebuildWidget();
AddChild(Overlay);
Icon = NewObject<UImage>();
Icon->SetDisplayLabel(TEXT("Icon"));
TextBlock = NewObject<UTextBlock>();
TextBlock->SetDisplayLabel(TEXT("Text"));
switch (ContentType)
{
case EContentType::WithIcon:
Overlay->AddChild(Icon);
break;
case EContentType::WithText:
Overlay->AddChild(TextBlock);
break;
case EContentType::WithTextAndIcon:
Overlay->AddChild(Icon);
Overlay->AddChild(TextBlock);
break;
}
if ( GetChildrenCount() > 0 )
{
Cast<UButtonSlot>(GetContentSlot())->BuildSlot(MyButton.ToSharedRef());
}
return ButtonRef;
}
void UUUIW_MasterButton::SynchronizeProperties()
{
Super::SynchronizeProperties();
Overlay->ClearChildren();
switch (ContentType)
{
case EContentType::WithIcon:
Overlay->AddChild(Icon);
break;
case EContentType::WithText:
Overlay->AddChild(TextBlock);
break;
case EContentType::WithTextAndIcon:
Overlay->AddChild(Icon);
Overlay->AddChild(TextBlock);
break;
}
}
Kinda 已经找到了解决方案。 PostEditChangeProperty(struct FPropertyChangedEvent & PropertyChangedEvent) 显然有效。但是它不是在值更改时调用,而是在之后调用蓝图编译(这就是为什么我认为它之前不起作用)
每次从小部件编辑器更改枚举变量 属性 时,我都必须更改子列表。
None 到目前为止我尝试过的功能似乎都有效(virtual void OnEndEditByDesigner(); virtual void PostEditChangeProperty(struct FPropertyChangedEvent & PropertyChangedEvent)).
SynchronizeProperties 文档指出
It can also be called by the editor to update modified state, so ensure all initialization to a widgets properties are performed here, or the property and visual state may become unsynced.
所以我不完全确定它是 use/overwrite 的正确函数(因为编辑器只能“可以”调用它来更新修改后的状态,不会在 属性编辑编辑)
下面是一些示例代码,展示了到目前为止我一直在尝试做的事情。
示例代码:
SampleButton.h
/* Includes */
#include "CoreMinimal.h"
#include "UObject/Object.h"
#include "Components/Button.h"
#include "Components/Image.h"
#include "Components/CanvasPanel.h"
#include "Components/ButtonSlot.h"
#include "Widgets/SOverlay.h"
#include "Components/Overlay.h"
#include "Components/TextBlock.h"
#include "Styling/SlateBrush.h"
#include "UUIW_MasterButton.generated.h"
//
UENUM(BlueprintType)
enum class EContentType : uint8
{
WithIcon,
WithText,
}
class SAMPLE_API SampleButton : public UButton
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintSetter=SetType, meta = (MakeEditWidget = ""))
EContentType ContentType = EContentType::WithIcon;
UPROPERTY(meta = (EditCondition = "ContentType == EContentType::WithIcon || ContentType == EContentType::WithTextAndIcon", EditConditionHides))
UImage* Icon;
UPROPERTY(meta = (EditCondition = "ContentType == EContentType::WithText || ContentType == EContentType::WithTextAndIcon", EditConditionHides))
UTextBlock* TextBlock;
protected:
virtual TSharedRef<SWidget> RebuildWidget() override;
UOverlay* Overlay;
virtual void SynchronizeProperties();
}
SampleButton.cpp
#include "UI/SampleButton.h"
TSharedRef<SWidget> SampleButton::RebuildWidget()
{
Overlay = NewObject<UOverlay>();
auto ButtonRef = Super::RebuildWidget();
AddChild(Overlay);
Icon = NewObject<UImage>();
Icon->SetDisplayLabel(TEXT("Icon"));
TextBlock = NewObject<UTextBlock>();
TextBlock->SetDisplayLabel(TEXT("Text"));
switch (ContentType)
{
case EContentType::WithIcon:
Overlay->AddChild(Icon);
break;
case EContentType::WithText:
Overlay->AddChild(TextBlock);
break;
case EContentType::WithTextAndIcon:
Overlay->AddChild(Icon);
Overlay->AddChild(TextBlock);
break;
}
if ( GetChildrenCount() > 0 )
{
Cast<UButtonSlot>(GetContentSlot())->BuildSlot(MyButton.ToSharedRef());
}
return ButtonRef;
}
void UUUIW_MasterButton::SynchronizeProperties()
{
Super::SynchronizeProperties();
Overlay->ClearChildren();
switch (ContentType)
{
case EContentType::WithIcon:
Overlay->AddChild(Icon);
break;
case EContentType::WithText:
Overlay->AddChild(TextBlock);
break;
case EContentType::WithTextAndIcon:
Overlay->AddChild(Icon);
Overlay->AddChild(TextBlock);
break;
}
}
Kinda 已经找到了解决方案。 PostEditChangeProperty(struct FPropertyChangedEvent & PropertyChangedEvent) 显然有效。但是它不是在值更改时调用,而是在之后调用蓝图编译(这就是为什么我认为它之前不起作用)