Making Menus in Py?

I’ve been starting my dip into UE Python and I have a simple script but since it’s made for artists I need to be able to put it on a menu. I see that there is some mentions to ToolMenu in the py docs but I can not for the life of me get it to not error.
So I guess my first question is

A) are the py docs online actually wrong? I ask this because looking at
https://docs.unrealengine.com/en-US/…ight=toolmenus
This says the find_menu wants a name but if I give it a unreal.Name or a string it complains about wanting something else entirely.

B) is there anyone that has made menus in Py and could show me some example code? I just need to get started with it and I’m sure I can sort it out after that…

Thanks for any help

PS. When is Epic going to update to py3? The VFX standard has been changed for a good chunk of time already…

Hi!

Can’t help with a)… sorry.

but for B):
You might wanna look at this:

This guy’s tutorial helped me to learn the ropes when it comes to Unreal python UI, he has a github up as well so you might wanna take a look at his code.

Hey thanks for the reply. Actually that is how I started getting my UI’s in UE. I have PySide2 working and some subclasses (based on that vid) for making windows and what not.
That’s the exact reason I’m trying to get menu’s made now, so I can get these tools sorted into a menu for the end user(s)
If I could get access to a base Qt window in UE I could probably just force a menu into it like you do regularly with PySide2/Qt stuff but I haven’t been able to get a hold of a main window…


"""

  Example of extending a menu in Unreal using Python

"""

import unreal

def main():

  menus = unreal.ToolMenus.get()

  # Find the 'edit' menu, this should not fail,
  # but if we're looking for a menu we're unsure about 'if not'
  # works as nullptr check,
  edit = menus.find_menu("LevelEditor.MainMenu.Edit")
  if not edit:
    print("Failed to find the 'Edit' menu")

  entry = unreal.ToolMenuEntry(
    name = "MyEntry",
    type = unreal.MultiBlockType.MENU_ENTRY, # If you pass a type that is not supported Unreal will let you know,
    insert_position = unreal.ToolMenuInsert("Delete", unreal.ToolMenuInsertType.AFTER) # this will tell unreal to insert this entry after the 'Delete' menu item, if found in section we define later,
  )

  edit.add_menu_entry("EditMain", entry) # section name, ToolMenuInsert, Unreal will add the section name if it can't find it, otherwise call AddEntry for the found section,

if __name__ == '__main__':
  main()

Added an extra line as I wasn’t getting Text on the entry (it was making the entry but leaving it blank)

I can’t seem to edit my above post so excuse the double post

Here is a sample of how to get a new menu added to the menubar and add an item to it (with example of how to make it execute py code)

Huzzah, with a lot of help from Andreas, I was able to get some menu items added to a new menu in Py :smiley:



import unreal

def main():
    print("Creating Menus!")
    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("LevelEditor.MainMenu")
    if not main_menu:
        print("Failed to find the 'Main' menu. Something is wrong in the force!")

    entry = unreal.ToolMenuEntry(
                                name="Python.Tools",
                                # 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("YourMenuItemName")
    # this is what gets executed on click
    entry.set_string_command(unreal.ToolMenuStringCommandType.PYTHON, string=("from foo import bar;bar.main()"))
    # add a new menu called PyTools to the MainMenu bar. You should probably rename the last 3 properties here to useful things for you
    script_menu = main_menu.add_sub_menu(main_menu.get_name(), "PythonTools", "Tools", "PyTools")
    # add our new entry to the new menu
    script_menu.add_menu_entry("Scripts",entry)
    # refresh the UI
    menus.refresh_all_widgets()


if __name__ == '__main__':
  main()




Next thing I’m trying to tackle is ContextMenus, specifically making/adding menu entries/sub menus to context menus based on the asset type that is being called on (such as the Skeletal Mesh specific options when you right click on a SK mesh.)
I’ve been trying to sort it out based off of how the C++ code does it but I haven’t figured that out entirely yet :frowning:
Does anyone have an idea if you can setup a menu based on just a class type?

Useful post, I was looking for just this information. Do you know if you can give the entry a python command instead of the command string? It would be good to be able to directly trigger a python method rather than have to execute a string.

As far as I’m able to tell it is only a string command. There is some other stuff in the docs that look to me like you should be able to give “ScriptObject” or something like that but I was unable to make it work myself. Personally I don’t mind the string cause it’s not the end of the world to me and I only make the menu at start up anyways (or reload etc)
I’d love to find out if you can just pass the object itself though.

Did you ever get anywhere with making the context menus work? Looking at the ToolMenu it’s hard to know what the list of possible menus are to be able to get them and extend them…