UE5 c++ adds a custom UserWdiget to the corresponding menu bar

Foreword:

In order to implement right-click addition consistent with UserWidget, this chapter is created
Note: UE5.3 is used here

Target content:

You can refer to the source code of UserWidget here, and copy it to your own. (This chapter just changed it all to your own CommonUserWidget)

Runtime module needs to add content

First create an object of your own Runtime module. I named it UCommonUserWidget.

.h

#pragma once

#include "Blueprint/UserWidget.h"
#include "CommonUserWidget.generated.h"

UCLASS(BlueprintType, Blueprintable)
class DIVINEPROLOGUE_API UCommonUserWidget : public UUserWidget
{<!-- -->
GENERATED_BODY()
public:
}
};

The main implementation content is: UFactory
Here you need to create an Editor module and add the following code:

.h

//This was created because in the spirit of changing everything, a copy was created.
#pragma once
#include "WidgetBlueprint.h"
#include "CommonWidgetBlueprint.generated.h"

/**
 * The widget blueprint enables extending UCommonWidgetBlueprint the user extensible UWidget.
 */
UCLASS(BlueprintType)
class UCommonWidgetBlueprint : public UWidgetBlueprint
{<!-- -->
GENERATED_BODY()
public:
UCommonWidgetBlueprint(){<!-- -->}
};

.h

// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
#include "Templates/SubclassOf.h"
#include "Factories/Factory.h"
#include "Engine/Blueprint.h"
#include "CommonUserWidgetFactory.generated.h"

UCLASS(HideCategories=Object, MinimalAPI)
class UCommonUserWidgetFactory : public UFactory
{<!-- -->
GENERATED_UCLASS_BODY()

// The type of blueprint that will be created
UPROPERTY(EditAnywhere, Category=WidgetBlueprintFactory)
TEnumAsByte<enum EBlueprintType> BlueprintType;

// The parent class of the created blueprint
UPROPERTY(EditAnywhere, Category=WidgetBlueprintFactory, meta=(AllowAbstract = ""))
TSubclassOf<class UUserWidget> ParentClass;

//~ Begin UFactory Interface
virtual bool ConfigureProperties() override;
virtual bool ShouldShowInNewMenu() const override;
virtual UObject* FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn, FName CallingContext) override;
virtual UObject* FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) override;
//~ Begin UFactory Interface

private:
UPROPERTY(Transient)
TObjectPtr<UClass> RootWidgetClass;
};

.cpp

// Copyright Epic Games, Inc. All Rights Reserved.

#include "CommonUserWidgetFactory.h"
#include "UObject/Interface.h"
#include "Misc/MessageDialog.h"
#include "Blueprint/UserWidget.h"
#include "Blueprint/WidgetBlueprintGeneratedClass.h"
#include "WidgetBlueprint.h"
#include "Kismet2/KismetEditorUtilities.h"
#include "Modules/ModuleManager.h"
#include "UMGEditorModule.h"

#include "Blueprint/WidgetTree.h"
#include "UMGEditorProjectSettings.h"
#include "ClassViewerModule.h"
#include "Kismet2/SClassPickerDialog.h"
#include "ClassViewerFilter.h"
#include "CommonUserWidget.h"
#include "CommonWidgetBlueprint.h"
#include "Components/CanvasPanel.h"

#define LOCTEXT_NAMESPACE "UCommonUserWidgetFactory"

/*------------------------------------------------ ----------------------------------
UCommonUserWidgetFactory implementation.
-------------------------------------------------- ----------------------------*/

class FWidgetClassFilter : public IClassViewerFilter
{<!-- -->
public:
/** All children of these classes will be included unless filtered out by another setting. */
TSet <const UClass*> AllowedChildrenOfClasses;

/** Disallowed class flags. */
EClassFlags DisallowedClassFlags;

virtual bool IsClassAllowed(const FClassViewerInitializationOptions & amp; InInitOptions, const UClass* InClass, TSharedRef< FClassViewerFilterFuncs > InFilterFuncs) override
{<!-- -->
return !InClass->HasAnyClassFlags(DisallowedClassFlags)
& amp; & amp; InFilterFuncs->IfInChildOfClassesSet(AllowedChildrenOfClasses, InClass) != EFilterReturn::Failed;
}
\t
virtual bool IsUnloadedClassAllowed(const FClassViewerInitializationOptions & amp; InInitOptions, const TSharedRef< const IUnloadedBlueprintData > InUnloadedClassData, TSharedRef< FClassViewerFilterFuncs > InFilterFuncs) override
{<!-- -->
return !InUnloadedClassData->HasAnyClassFlags(DisallowedClassFlags)
& amp; & amp; InFilterFuncs->IfInChildOfClassesSet(AllowedChildrenOfClasses, InUnloadedClassData) != EFilterReturn::Failed;
}

};

UCommonUserWidgetFactory::UCommonUserWidgetFactory(const FObjectInitializer & ObjectInitializer)
: Super(ObjectInitializer)
{<!-- -->
bCreateNew = true;
bEditAfterNew = true;
SupportedClass = UCommonWidgetBlueprint::StaticClass();
ParentClass = nullptr;
}

bool UCommonUserWidgetFactory::ConfigureProperties()
{<!-- -->
if (GetDefault<UUMGEditorProjectSettings>()->bUseUserWidgetParentClassViewerSelector || GetDefault<UUMGEditorProjectSettings>()->bUseUserWidgetParentDefaultClassViewerSelector)
{<!-- -->
FClassViewerModule & ClassViewerModule = FModuleManager::LoadModuleChecked<FClassViewerModule>("ClassViewer");

// Fill in options
FClassViewerInitializationOptions Options;
Options.DisplayMode = EClassViewerDisplayMode::Type::TreeView;
Options.Mode = EClassViewerMode::ClassPicker;
Options.bShowNoneOption = false;
Options.bExpandAllNodes = true;
Options.bShowDefaultClasses = GetDefault<UUMGEditorProjectSettings>()->bUseUserWidgetParentDefaultClassViewerSelector;
Options.bShowClassesViewer = GetDefault<UUMGEditorProjectSettings>()->bUseUserWidgetParentClassViewerSelector;

TSharedPtr<FWidgetClassFilter> Filter = MakeShareable(new FWidgetClassFilter);
Options.ClassFilters.Add(Filter.ToSharedRef());

const TArray<TSoftClassPtr<UUserWidget>> & amp; FavoriteWidgetParentClasses = GetDefault<UUMGEditorProjectSettings>()->FavoriteWidgetParentClasses;
for (int32 Index = 0; Index < FavoriteWidgetParentClasses.Num(); + + Index)
{<!-- -->
UClass* FavoriteWidgetParentClass = FavoriteWidgetParentClasses[Index].LoadSynchronous();
if (FavoriteWidgetParentClass & amp; & amp; FavoriteWidgetParentClass->IsChildOf(UCommonUserWidget::StaticClass()))
{<!-- -->
if (!Options.ExtraPickerCommonClasses.Contains(FavoriteWidgetParentClass))
{<!-- -->
Options.ExtraPickerCommonClasses.Add(FavoriteWidgetParentClass);
}
}
}

if (Options.ExtraPickerCommonClasses.Num() == 0)
{<!-- -->
Options.ExtraPickerCommonClasses.Add(UCommonUserWidget::StaticClass());
}

Filter->DisallowedClassFlags = CLASS_Deprecated | CLASS_NewerVersionExists | CLASS_Hidden | CLASS_HideDropDown;
Filter->AllowedChildrenOfClasses.Add(UCommonUserWidget::StaticClass());

const FText TitleText = LOCTEXT("CreateCommonWidgetBlueprint", "Pick Parent Class for New Widget Blueprint");

UClass* ChosenParentClass = nullptr;
bool isSuccessful = SClassPickerDialog::PickClass(TitleText, Options, ChosenParentClass, UCommonUserWidget::StaticClass());
ParentClass = ChosenParentClass ? ChosenParentClass : UCommonUserWidget::StaticClass();

if (!isSuccessful)
{<!-- -->
return false;
}
}

if (GetDefault<UUMGEditorProjectSettings>()->bUseWidgetTemplateSelector)
{<!-- -->
// Load the classviewer module to display a class picker
FClassViewerModule & ClassViewerModule = FModuleManager::LoadModuleChecked<FClassViewerModule>("ClassViewer");

// Fill in options
FClassViewerInitializationOptions Options;
Options.Mode = EClassViewerMode::ClassPicker;
Options.bShowNoneOption = true;

TArray<TSoftClassPtr<UPanelWidget>> CommonRootWidgetClasses = GetDefault <UUMGEditorProjectSettings>()->CommonRootWidgetClasses;
for (int32 Index = 0; Index < CommonRootWidgetClasses.Num(); + + Index)
{<!-- -->
UClass* PanelWidgetClass = CommonRootWidgetClasses[Index].LoadSynchronous();
if (PanelWidgetClass & amp; & amp; PanelWidgetClass->IsChildOf(UPanelWidget::StaticClass()))
{<!-- -->
if (!Options.ExtraPickerCommonClasses.Contains(PanelWidgetClass))
{<!-- -->
Options.ExtraPickerCommonClasses.Add(PanelWidgetClass);
}
}
}

if (Options.ExtraPickerCommonClasses.Num() == 0)
{<!-- -->
Options.ExtraPickerCommonClasses.Add(UCanvasPanel::StaticClass());
}

TSharedPtr<FWidgetClassFilter> Filter = MakeShareable(new FWidgetClassFilter);
Options.ClassFilters.Add(Filter.ToSharedRef());

Filter->DisallowedClassFlags = CLASS_Abstract | CLASS_Deprecated | CLASS_NewerVersionExists;
Filter->AllowedChildrenOfClasses.Add(UPanelWidget::StaticClass());

const FText TitleText = LOCTEXT("CreateRootWidgetBlueprint", "Pick Root Widget for New Widget Blueprint");
return SClassPickerDialog::PickClass(TitleText, Options, static_cast<UClass* &>(RootWidgetClass), UPanelWidget::StaticClass());

}
return true;
}

bool UCommonUserWidgetFactory::ShouldShowInNewMenu() const
{<!-- -->
return true;
}

UObject* UCommonUserWidgetFactory::FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn, FName CallingContext)
{<!-- -->
// Make sure we are trying to factory an Anim Blueprint, then create and init one
check(Class->IsChildOf(UCommonWidgetBlueprint::StaticClass()));

UClass* CurrentParentClass = ParentClass;
if (CurrentParentClass == nullptr)
{<!-- -->
CurrentParentClass = UCommonUserWidget::StaticClass();
}

// If they selected an interface, force the parent class to be UInterface
if (BlueprintType == BPTYPE_Interface)
{<!-- -->
CurrentParentClass = UInterface::StaticClass();
}

if ( (CurrentParentClass == nullptr) || !FKismetEditorUtilities::CanCreateBlueprintOfClass(CurrentParentClass) || !CurrentParentClass->IsChildOf(UCommonUserWidget::StaticClass()) )
{<!-- -->
FFormatNamedArguments Args;
Args.Add( TEXT("ClassName"), CurrentParentClass ? FText::FromString( CurrentParentClass->GetName()) : LOCTEXT("Null", "(null)") );
FMessageDialog::Open( EAppMsgType::Ok, FText::Format( LOCTEXT("CannotCreateCommonWidgetBlueprint", "Cannot create a Common Widget Blueprint based on the class '{ClassName}'."), Args ) ) ;
return nullptr;
}
else
{<!-- -->
if (!GetDefault<UUMGEditorProjectSettings>()->bUseWidgetTemplateSelector)
{<!-- -->
RootWidgetClass = GetDefault<UUMGEditorProjectSettings>()->DefaultRootWidget;
}

UCommonWidgetBlueprint* NewBP = CastChecked<UCommonWidgetBlueprint>(FKismetEditorUtilities::CreateBlueprint(CurrentParentClass, InParent, Name, BlueprintType, UCommonWidgetBlueprint::StaticClass(), UWidgetBlueprintGeneratedClass::StaticClass(), CallingContext));

// Create the desired root widget specified by the project
if (NewBP->WidgetTree->RootWidget == nullptr)
{<!-- -->
if (TSubclassOf<UPanelWidget> RootWidgetPanel = RootWidgetClass)
{<!-- -->
UWidget* Root = NewBP->WidgetTree->ConstructWidget<UWidget>(RootWidgetPanel);
NewBP->WidgetTree->RootWidget = Root;
}
}

{<!-- -->
IUMGEditorModule::FWidgetBlueprintCreatedArgs Args;
Args.ParentClass = CurrentParentClass;
Args.Blueprint = NewBP;

IUMGEditorModule & amp; UMGEditor = FModuleManager::LoadModuleChecked<IUMGEditorModule>("UMGEditor");
UMGEditor.OnWidgetBlueprintCreated().Broadcast(Args);
}

return NewBP;
}
}

UObject* UCommonUserWidgetFactory::FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn)
{<!-- -->
return FactoryCreateNew(Class, InParent, Name, Flags, Context, Warn, NAME_None);
}

#undef LOCTEXT_NAMESPACE

After running like this, you will find that the right-click content already exists, but the name is wrong and the type is wrong, but it can be created normally because we also need to create a UAssetDefinitionDefault

.h

// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once
#include "CoreMinimal.h"
#include "AssetDefinitionDefault.h"

#include "AssetDefinition_CommonWidgetBlueprint.generated.h"

UCLASS()
class UAssetDefinition_CommonWidgetBlueprint : public UAssetDefinitionDefault
{<!-- -->
GENERATED_BODY()

public:
UAssetDefinition_CommonWidgetBlueprint();
virtual ~UAssetDefinition_CommonWidgetBlueprint() override;
\t
// UAssetDefinition Begin
virtual FText GetAssetDisplayName() const override;
virtual FLinearColor GetAssetColor() const override;
virtual TSoftClassPtr<UObject> GetAssetClass() const override;
virtual TConstArrayView<FAssetCategoryPath> GetAssetCategories() const override;
virtual EAssetCommandResult OpenAssets(const FAssetOpenArgs & amp; OpenArgs) const override;
virtual EAssetCommandResult PerformAssetDiff(const FAssetDiffArgs & amp; DiffArgs) const override;
virtual FText GetAssetDescription(const FAssetData & amp; AssetData) const override;
// UAssetDefinition End
};

.cpp

#include "AssetDefinition_CommonWidgetBlueprint.h"
#include "CommonWidgetBlueprint.h"
#include "WidgetBlueprintEditor.h"
#include "Misc/MessageDialog.h"
#include "SBlueprintDiff.h"

#define LOCTEXT_NAMESPACE "AssetTypeActions"

UAssetDefinition_CommonWidgetBlueprint::UAssetDefinition_CommonWidgetBlueprint() = default;

UAssetDefinition_CommonWidgetBlueprint::~UAssetDefinition_CommonWidgetBlueprint() = default;

FText UAssetDefinition_CommonWidgetBlueprint::GetAssetDisplayName() const
{<!-- -->
return LOCTEXT("UAssetDefinition_CommonWidgetBlueprint", "Common Widget Blueprint");
}

FLinearColor UAssetDefinition_CommonWidgetBlueprint::GetAssetColor() const
{<!-- -->
return FLinearColor(FColor(44, 89, 180));
}

TSoftClassPtr<> UAssetDefinition_CommonWidgetBlueprint::GetAssetClass() const
{<!-- -->
return UCommonWidgetBlueprint::StaticClass();
}

TConstArrayView<FAssetCategoryPath> UAssetDefinition_CommonWidgetBlueprint::GetAssetCategories() const
{<!-- -->
static const TArray<FAssetCategoryPath, TFixedAllocator<1>> Categories = {<!-- --> EAssetCategoryPaths::UI };
return Categories;
}

EAssetCommandResult UAssetDefinition_CommonWidgetBlueprint::OpenAssets(const FAssetOpenArgs & amp; OpenArgs) const
{<!-- -->
EToolkitMode::Type Mode = OpenArgs.GetToolkitMode();

EAssetCommandResult Result = EAssetCommandResult::Unhandled;

for (UBlueprint* Blueprint : OpenArgs.LoadObjects<UBlueprint>())
{<!-- -->
if (Blueprint & amp; & amp; Blueprint->SkeletonGeneratedClass & amp; & amp; Blueprint->GeneratedClass)
{<!-- -->
TSharedRef<FWidgetBlueprintEditor> NewBlueprintEditor(new FWidgetBlueprintEditor);

const bool bShouldOpenInDefaultsMode = false;
TArray<UBlueprint*> Blueprints;
Blueprints.Add(Blueprint);

NewBlueprintEditor->InitWidgetBlueprintEditor(Mode, OpenArgs.ToolkitHost, Blueprints, bShouldOpenInDefaultsMode);
}
else
{<!-- -->
FMessageDialog::Open( EAppMsgType::Ok, LOCTEXT("FailedToLoadWidgetBlueprint", "Widget Blueprint could not be loaded because it derives from an invalid class.\\
Check to make sure the parent class for this blueprint hasn't been removed!"));
}

Result = EAssetCommandResult::Handled;
}

return Result;
}

EAssetCommandResult UAssetDefinition_CommonWidgetBlueprint::PerformAssetDiff(const FAssetDiffArgs & amp; DiffArgs) const
{<!-- -->
const UBlueprint* OldBlueprint = Cast<UBlueprint>(DiffArgs.OldAsset);
const UBlueprint* NewBlueprint = Cast<UBlueprint>(DiffArgs.NewAsset);
UClass* AssetClass = GetAssetClass().Get();
SBlueprintDiff::CreateDiffWindow(OldBlueprint, NewBlueprint, DiffArgs.OldRevision, DiffArgs.NewRevision, AssetClass);
return EAssetCommandResult::Handled;
}

FText UAssetDefinition_CommonWidgetBlueprint::GetAssetDescription(const FAssetData & amp; AssetData) const
{<!-- -->
FString Description = AssetData.GetTagValueRef<FString>( GET_MEMBER_NAME_CHECKED( UBlueprint, BlueprintDescription ) );
if ( !Description.IsEmpty() )
{<!-- -->
Description.ReplaceInline( TEXT( "\\
" ), TEXT( "\\
" ) );
return FText::FromString( MoveTemp(Description) );
}

return FText::GetEmpty();
}

#undef LOCTEXT_NAMESPACE

At this point we get the result we want:

Add the test code to your UserWidget and find that it can be processed normally by reflection, so this article is completed.



Yes, don’t forget to add the Editor module:

 "UnrealEd",
        "UMGEditor",
        "UMG",
        "AssetDefinition",
        "Kismet",

Runtime module:

 "UMG",


But this will only find that the newly created control cannot appear normally in the blueprint, because if you look carefully at its module, it actually adds a lot of support because of this. Therefore, we finally consider creating UWidgetBlueprint here, but the supported SupportClass is still ours A custom Class is enough. In this way, we can use a set of variable reflections supported by UserWdiget. It does a lot of internal processing for this part of UI mapping, so we do not consider writing this part ourselves. We only need to actually create it in Factory. Just modify the position.
FactoryCreateNew method modification:

UObject* UCommonUserWidgetFactory::FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn, FName CallingContext)
{<!-- -->
// Make sure we are trying to factory an Anim Blueprint, then create and init one
check(Class->IsChildOf(UCommonWidgetBlueprint::StaticClass()));

UClass* CurrentParentClass = ParentClass;
if (CurrentParentClass == nullptr)
{<!-- -->
CurrentParentClass = UCommonUserWidget::StaticClass();
}

// If they selected an interface, force the parent class to be UInterface
if (BlueprintType == BPTYPE_Interface)
{<!-- -->
CurrentParentClass = UInterface::StaticClass();
}

if ( (CurrentParentClass == nullptr) || !FKismetEditorUtilities::CanCreateBlueprintOfClass(CurrentParentClass) || !CurrentParentClass->IsChildOf(UCommonUserWidget::StaticClass()) )
{<!-- -->
FFormatNamedArguments Args;
Args.Add( TEXT("ClassName"), CurrentParentClass ? FText::FromString( CurrentParentClass->GetName()) : LOCTEXT("Null", "(null)") );
FMessageDialog::Open( EAppMsgType::Ok, FText::Format( LOCTEXT("CannotCreateCommonWidgetBlueprint", "Cannot create a Common Widget Blueprint based on the class '{ClassName}'."), Args ) ) ;
return nullptr;
}
else
{<!-- -->
if (!GetDefault<UUMGEditorProjectSettings>()->bUseWidgetTemplateSelector)
{<!-- -->
RootWidgetClass = GetDefault<UUMGEditorProjectSettings>()->DefaultRootWidget;
}
----------------------------------Modification part----------------- ---------------
UWidgetBlueprint* NewBP = CastChecked<UWidgetBlueprint>(FKismetEditorUtilities::CreateBlueprint(CurrentParentClass, InParent, Name, BlueprintType, UWidgetBlueprint::StaticClass(), UWidgetBlueprintGeneratedClass::StaticClass(), CallingContext));

// Create the desired root widget specified by the project
if (NewBP->WidgetTree->RootWidget == nullptr)
{<!-- -->
if (TSubclassOf<UPanelWidget> RootWidgetPanel = RootWidgetClass)
{<!-- -->
UWidget* Root = NewBP->WidgetTree->ConstructWidget<UWidget>(RootWidgetPanel);
NewBP->WidgetTree->RootWidget = Root;
}
}

{<!-- -->
IUMGEditorModule::FWidgetBlueprintCreatedArgs Args;
Args.ParentClass = CurrentParentClass;
Args.Blueprint = NewBP;

IUMGEditorModule & amp; UMGEditor = FModuleManager::LoadModuleChecked<IUMGEditorModule>("UMGEditor");
UMGEditor.OnWidgetBlueprintCreated().Broadcast(Args);
}

return NewBP;
}
}

Unfortunately, it is not cost-effective in terms of time to process this part of the content myself, but when it comes to final creation, it is still ideal to choose our custom content.

This is the end of the article. Of course, some people may prefer to make some obvious icons like me for easy selection. Here you only need to add Style:
Editor module:

.h

// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "Styling/SlateStyle.h"

/** Manages the style which provides resources for niagara editor widgets. */
class FDivinePrologueEditorStyle : public FSlateStyleSet
{<!-- -->
public:
static void Register();
static void Unregister();
static void Shutdown();

/** reloads textures used by slate renderer */
static void ReloadTextures();

/** @return The Slate style set for niagara editor widgets */
static const FDivinePrologueEditorStyle & amp; Get();

static void ReinitializeStyle();
virtual const FName & amp; GetStyleSetName() const override;

private:
FDivinePrologueEditorStyle();
void InitIcons();
\t
static TSharedPtr<FDivinePrologueEditorStyle> DivinePrologueEditorStyle;
};
.cpp
// Copyright Epic Games, Inc. All Rights Reserved.

#include "DivinePrologueEditorStyle.h"
#include "Styling/SlateStyleMacros.h"
#include "Styling/SlateStyleRegistry.h"

TSharedPtr<FDivinePrologueEditorStyle> FDivinePrologueEditorStyle::DivinePrologueEditorStyle = nullptr;

void FDivinePrologueEditorStyle::Register()
{<!-- -->
FSlateStyleRegistry::RegisterSlateStyle(Get());
}

void FDivinePrologueEditorStyle::Unregister()
{<!-- -->
FSlateStyleRegistry::UnRegisterSlateStyle(Get());
}

void FDivinePrologueEditorStyle::Shutdown()
{<!-- -->
Unregister();
DivinePrologueEditorStyle.Reset();
}

const FVector2D Icon8x8(8.0f, 8.0f);
const FVector2D Icon12x12(12.0f, 12.0f);
const FVector2D Icon16x16(16.0f, 16.0f);
const FVector2D Icon20x20(20.0f, 20.0f);
const FVector2D Icon32x32(32.0f, 32.0f);
const FVector2D Icon40x40(40.0f, 40.0f);
const FVector2D Icon64x64(64.0f, 64.0f);

FDivinePrologueEditorStyle::FDivinePrologueEditorStyle() : FSlateStyleSet("DivinePrologueEditorStyle")
{<!-- -->
FSlateStyleSet::SetContentRoot(FPaths::ProjectContentDir() / TEXT("StyleTextures"));
FSlateStyleSet::SetCoreContentRoot(FPaths::ProjectContentDir() / TEXT("StyleTextures"));
\t
InitIcons();
}

void FDivinePrologueEditorStyle::InitIcons()
{<!-- -->
Set("CommonUserWidget.Icon", new IMAGE_BRUSH("Icon", Icon64x64));
}

void FDivinePrologueEditorStyle::ReloadTextures()
{<!-- -->
FSlateApplication::Get().GetRenderer()->ReloadTextureResources();
}

const FDivinePrologueEditorStyle & amp; FDivinePrologueEditorStyle::Get()
{<!-- -->
if(!DivinePrologueEditorStyle.IsValid())
{<!-- -->
DivinePrologueEditorStyle = MakeShareable(new FDivinePrologueEditorStyle());
}
\t
return *DivinePrologueEditorStyle;
}

void FDivinePrologueEditorStyle::ReinitializeStyle()
{<!-- -->
Unregister();
DivinePrologueEditorStyle.Reset();
Register();
}

const FName & amp; FDivinePrologueEditorStyle::GetStyleSetName() const
{<!-- -->
static FName StyleName("DivinePrologueEditorStyle");
return StyleName;
}

This is my path:
Of course, after creation, you need to register it when the module starts:

Override the following method in UCommonUserWidgetFactory to return the corresponding image in our Style:

 virtual FName GetNewAssetThumbnailOverride() const override
{<!-- -->
return TEXT("CommonUserWidget.Icon");
}