How to make an EditorUtilityWidget open/run via C++

Hey,
I am working on a UE4 project for university and I am creating a small editor plugin to procedurally generate buildings.

Unfortunately I can not seem to find a way to start the editor utility widget by pressing the toolbar button/using C++.
I already tried to use CreateWidget, but it does not seem to work with EditorUtilityWidgets.

I realized that there is very little information to find for this problem.
Does anyone have an idea how to run an EditorUtilityWidget via C++?

Best regards

Hi,
In c++ you cas use this code for run editor utility widget

void YourClassName::RunEditorUtilityWidget(UEditorUtilityWidgetBlueprint* EditorWidget)
{
	if (EditorWidget)
	{
		UEditorUtilitySubsystem* EditorUtilitySubsystem = GEditor->GetEditorSubsystem<UEditorUtilitySubsystem>();
		EditorUtilitySubsystem->SpawnAndRegisterTab(EditorWidget);
	}
}

Or in blueprint there are tutoriel on the Wiki

Ah thanks for the function!

Unfortunately I can’t get the reference to the Widget right.
Do you also know how to properly reference the EditorWidget, since I can’t seem to get it to work with ConstructorHelper::ClassFinder.

This is the code I want to use when pressing the toolbar button:

void FPlugiModule::PluginButtonClicked()
{

static ConstructorHelpers::FClassFinder<UEditorUtilityWidgetBlueprint> BBObj(TEXT("/Game/BB"));
if (BBObj.Succeeded()) {
	//MenuClass is TSubclassOf<class UEditorUtilityWidgetBlueprint> MenuClass;
	MenuClass = BBObj.Class;
}

//Does not work as it can't convert UClass to UEditorUtilityWidgetBlueprint
RunEditorUtilityWidget(MenuClass.Get());

}

I FINALLY GOT IT TO WORK!

If anyone is still wondering, since it’s hard to find the solution to this. I decided to share what I found.
I found this random chinese website, that posted like just a month ago and it shows a working way to open them via C++:

This is working for a Standalone Window Editor Plugin:

TSharedRef FVIR_ENVIRONMENTModule::OnSpawnPluginTab(const FSpawnTabArgs& SpawnTabArgs)
{

// load UMG Of BP
UBlueprint* UMGBP = LoadObject<UBlueprint>(nullptr, L"/Game/yaksueEditorUtilityWidgetBlueprint"); //Reference to your EditorUtilityWidget

// Modelled on the  UEditorUtilityWidgetBlueprint::CreateUtilityWidget()  Do it again 
TSharedRef<SWidget> TabWidget = SNullWidget::NullWidget;
{

	UEditorUtilityWidget* CreatedUMGWidget = nullptr;// Created UMG Control 

	UClass* BlueprintClass = UMGBP->GeneratedClass;
	TSubclassOf<UEditorUtilityWidget> WidgetClass = BlueprintClass;
	UWorld* World = GEditor->GetEditorWorldContext().World();
	if (World)
	{

		if (CreatedUMGWidget)
		{

			CreatedUMGWidget->Rename(nullptr, GetTransientPackage());
		}
		CreatedUMGWidget = CreateWidget<UEditorUtilityWidget>(World, WidgetClass);
	}
	if (CreatedUMGWidget)
	{

		TabWidget = SNew(SVerticalBox)
			+ SVerticalBox::Slot()
			.HAlign(HAlign_Fill)
			[
				CreatedUMGWidget->TakeWidget()
			];
	}
}

Don’t forget to do this: #include “Editor/Blutility/Classes/EditorUtilityWidget.h”

Also add
“UMGEditor”,
“Blutility”,
“UMG”

to your private dependencies in the Build.cs of the plugin.

All credits go to this post: Learn to use UMG as an editor control in the unreal engine

1 Like

What does the header for this look like?

This is my current attempt to make this work

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

#include "bplib.h"
#include "Editor/Blutility/Classes/EditorUtilityWidget.h"

#define LOCTEXT_NAMESPACE "FbplibModule"

void FbplibModule::StartupModule()
{
	// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
	
}

void FbplibModule::ShutdownModule()
{
	// This function may be called during shutdown to clean up your module.  For modules that support dynamic reloading,
	// we call this function before unloading the module.
	
}

void FbplibModule::PluginButtonClicked()
{
}

// Modelled on the  UEditorUtilityWidgetBlueprint::CreateUtilityWidget()  Do it again
TSharedRef FbplibModule::OnSpawnPluginTab(const FSpawnTabArgs& SpawnTabArgs)
	{
	UBlueprint* UMGBP = LoadObject<UBlueprint>(nullptr, L"/Script/Blutility.EditorUtilityWidgetBlueprint'/bplib/bplib.bplib'"); //Reference to your EditorUtilityWidget

	TSharedRef<SWidget> TabWidget = SNullWidget::NullWidget;
	{

		UEditorUtilityWidget* CreatedUMGWidget = nullptr;// Created UMG Control 

		UClass* BlueprintClass = UMGBP->GeneratedClass;
		TSubclassOf<UEditorUtilityWidget> WidgetClass = BlueprintClass;
		UWorld* World = GEditor->GetEditorWorldContext().World();
		if (World)
		{

			if (CreatedUMGWidget)
			{

				CreatedUMGWidget->Rename(nullptr, GetTransientPackage());
			}
			CreatedUMGWidget = CreateWidget<UEditorUtilityWidget>(World, WidgetClass);
		}
		if (CreatedUMGWidget)
		{

			TabWidget = SNew(SVerticalBox)
				+ SVerticalBox::Slot()
				.HAlign(HAlign_Fill)
				[
					CreatedUMGWidget->TakeWidget()
				];
		}
	}
	
}

#undef LOCTEXT_NAMESPACE
	
IMPLEMENT_MODULE(FbplibModule, bplib)

header

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

#pragma once

#include "CoreMinimal.h"
#include "Modules/ModuleManager.h"

class FbplibModule : public IModuleInterface
{
public:

	/** IModuleInterface implementation */
	virtual void StartupModule() override;
	virtual void ShutdownModule() override;
	
	/** This function will be bound to Command (by default it will bring up plugin window) */
	void PluginButtonClicked();

	TSharedRef OnSpawnPluginTab();
	
};

edit: got it to work, report later

This post was great, but as written can cause crashes when the level changes. So I did it this way calling the UEditorUtilityWidgetBlueprint method rather than rebuilding it:

TSharedRef<SDockTab> FYourModule::OnSpawnPluginTab(const FSpawnTabArgs& SpawnTabArgs)
{

	// load YourWidget as BPClass
	UEditorUtilityWidgetBlueprint* UMGBP = LoadObject<UEditorUtilityWidgetBlueprint>(nullptr, L"/Game/YourEUWBP"); 

	TSharedRef<SDockTab> SpawnedTab = UMGBP->SpawnEditorUITab(SpawnTabArgs);

	return SpawnedTab;
	
}

This works for me as a Menu Tab

3 Likes

This code worked great for me, using UEditorUtilitySubsystem

void FAutomationModule::OnSpawnPluginTab()
{
    // Reference to your AutomationUtilityWidget
    UBlueprint* UMGBP = LoadObject<UBlueprint>(nullptr, L"/Script/Blutility.EditorUtilityWidgetBlueprint'/Automation/EUW_ConsoleCommand.EUW_ConsoleCommand'");

    UEditorUtilityWidgetBlueprint* EditorWidget = Cast<UEditorUtilityWidgetBlueprint>(UMGBP);

    if (EditorWidget)
    {
        UEditorUtilitySubsystem* EditorUtilitySubsystem = GEditor->GetEditorSubsystem<UEditorUtilitySubsystem>();
        EditorUtilitySubsystem->SpawnAndRegisterTab(EditorWidget);
    }
}