While we can append additional items to context menus in Blender, context menus can also be completely redefined. Instead of the basic one, we can get a completely custom context menu with any set and order of items we need.
First, let’t define a function for rendering a custom menu with a set of operators that will be displayed as items in this new menu.
For example, we can take a set of operators that add basic mesh primitives to the scene.
1 2 3 4 5 6 7 8 9 10 11 |
def menu_override_draw_func(self, context): self.layout.operator('mesh.primitive_plane_add', text='Plane', icon='MESH_PLANE') self.layout.operator('mesh.primitive_cube_add', text='Cube', icon='MESH_CUBE') self.layout.operator('mesh.primitive_circle_add', text='Circle', icon='MESH_CIRCLE') self.layout.operator('mesh.primitive_uv_sphere_add', text='UV Sphere', icon='MESH_UVSPHERE') self.layout.operator('mesh.primitive_ico_sphere_add', text='Ico Sphere', icon='MESH_ICOSPHERE') self.layout.operator('mesh.primitive_cylinder_add', text='Cylinder', icon='MESH_CYLINDER') self.layout.operator('mesh.primitive_cone_add', text='Cone', icon='MESH_CONE') self.layout.operator('mesh.primitive_torus_add', text='Torus', icon='MESH_TORUS') self.layout.operator('mesh.primitive_grid_add', text='Grid', icon='MESH_GRID') self.layout.operator('mesh.primitive_monkey_add', text='Monkey', icon='MESH_MONKEY') |
The structure of the function is similar to the structure of the “draw” function in custom UI panel classes. Menu items are created by calling the “operator” function of the “self.layout” object.
Now we can completely redefine any context menu by replacing the pointer to its “draw” function with a pointer to our custom draw function.
For example, let’s redefine the main context menu of the 3D viewport.
1 |
bpy.types.VIEW3D_MT_object_context_menu.draw = menu_override_draw_func |
Now, when we right-click in the 3D viewport area, instead of the basic context menu, our custom menu will be displayed for quickly adding mesh primitives to the scene.
Hi, thanks for this awesome tutorial. I have a specific issue though.
I would like to completely override UIList’s context menu with a custom menu, but only for one specific UIList, that I am adding in my addon. For the rest already present UIlists (UVmaps, Vertex color, etc.) in Blender I wanna keep the original ones. Do you have any idea on how to do this?
Thank you
Hi!
Try the UI_MT_list_item_context_menu
To find what UIList user clicked, try the way from the official docs
https://docs.blender.org/api/current/bpy.types.Menu.html#extending-the-button-context-menu
using context.button_pointer and context.button_prop properties
THx for advice…I have looked into that. I also got the example code from the Docs somehow working to dump some of the context information when I click on new button in the UIlist context menu…but I have no idea how to use it further to achieve what I want….I am rather “noob” in this area…I started with the python scripting relatively recently 🙁
Maybe try more common and easy way? What action do you want to do with the context menu? For UILists it usually used a sidebar menu right of the uil-list itself. It works with the active element of the UIList. You can add any buttons with operators to work with the UIList.
https://i.imgur.com/Pa7pQ8k.jpg