Download

Adding menu entry in Python; script "works" but parameter meanings are unclear

Based on a previous forum post, and some web search, I now have a working script.
Here the post I used as example: https://forums.unrealengine.com/t/making-menus-in-py/144498/7

But there are multiple parameters in the script, whose meaning I do not understand. Here is the script:

import unreal

# Menu parameters
SRC_MENU = "LevelEditor.MainMenu"
SECTION_NAME = "PythonTools"
SUB_MENU_NAME = "Tools" 
SUB_MENU_LABEL = "PyTools"# Actual menu name in to toolbar

# Menu entry parameters
ENTRY_NAME = "Python.Tools"
ENTRY_LABEL = "YourMenuItemName" # Actual menu entry name
ENTRY_SECTION_NAME = "Scripts"
CUSTOM_TYPE = custom_type=unreal.Name("")
SCRIPT = "from foo import bar;bar.main()"

def main():
    menus = unreal.ToolMenus.get()
    # Find the 'Main' menu, this should not fail,
    # but if we're looking for a menu we're unsure about 'if not'
    # works as nullptr check,
    main_menu = menus.find_menu(SRC_MENU)
    if not main_menu:
        unreal.log_error("Failed to find the 'Main' menu. Something is wrong in the force!")
    else:
        unreal.log("Adding menu {} with label {} under section {} to menu {}".format(SUB_MENU_NAME, SUB_MENU_LABEL, SECTION_NAME, SRC_MENU))
        script_menu = main_menu.add_sub_menu(main_menu.get_name(), SECTION_NAME, SUB_MENU_NAME, SUB_MENU_LABEL)
        entry = unreal.ToolMenuEntry(
            name=ENTRY_NAME,
            # If you pass a type that is not supported Unreal will let you know,
            type=unreal.MultiBlockType.MENU_ENTRY,
            # this will tell unreal to insert this entry into the First spot of the menu
            insert_position=unreal.ToolMenuInsert("", unreal.ToolMenuInsertType.FIRST)
        )
        entry.set_label(ENTRY_LABEL)
        # this is what gets executed on click
        entry.set_string_command(unreal.ToolMenuStringCommandType.PYTHON, CUSTOM_TYPE, string=(SCRIPT))
        # add our new entry to the new menu
        unreal.log("Adding menu entry {} under section {} to menu {}".format(ENTRY_NAME, ENTRY_SECTION_NAME, SUB_MENU_NAME))
        script_menu.add_menu_entry(ENTRY_SECTION_NAME,entry)
        # refresh the UI
        menus.refresh_all_widgets()

if __name__ == '__main__':
    main()

So, my question is, what is the purpose of those parameters, which I cannot “see” after running the script:

SECTION_NAME
SUB_MENU_NAME
ENTRY_NAME
ENTRY_SECTION_NAME

I would have at least expected, ENTRY_LABEL to be under a section called ENTRY_SECTION_NAME, but it’s not.

Some you can see, with setting Editor Preferences->General->Miscellaneous->Display UI Extension Points => True

Take a look at the code used to make the menu for setting Lighting Build Quality in Engine/Source/Editor/LevelEditor/Private/LevelEditorMenu.cpp

		static void RegisterLightingQualityMenu(const FName InBaseMenuName)
		{
			UToolMenu* SubMenu = UToolMenus::Get()->RegisterMenu(UToolMenus::JoinMenuPaths(InBaseMenuName, "LightingQuality"));

			{
				FToolMenuSection& Section = SubMenu->AddSection("LevelEditorBuildLightingQuality", LOCTEXT("LightingQualityHeading", "Quality Level"));
				Section.AddMenuEntry(FLevelEditorCommands::Get().LightingQuality_Production);
				Section.AddMenuEntry(FLevelEditorCommands::Get().LightingQuality_High);
				Section.AddMenuEntry(FLevelEditorCommands::Get().LightingQuality_Medium);
				Section.AddMenuEntry(FLevelEditorCommands::Get().LightingQuality_Preview);
			}
		}

It creates a sub menu “LightingQuality”, then a section “LevelEditorBuildLightingQuality” and an entry for each command to set the quality which gets added to the section.

And you can see on this image section name, sub menu name etc are all there.

Most methods for extending and working with the menu will require that you provide these names and not the name of the label you see normally.

1 Like