Menu(bpy_struct)¶
Basic Menu Example¶
Here is an example of a simple menu. Menus differ from panels in that they must reference from a header, panel or another menu.
Notice the ‘CATEGORY_MT_name’ in Menu.bl_idname
, this is a naming
convention for menus.
Note
Menu subclasses must be registered before referencing them from blender.
Note
Menus have their Layout.operator_context
initialized as
‘EXEC_REGION_WIN’ rather than ‘INVOKE_DEFAULT’ (see Execution Context).
If the operator context needs to initialize inputs from the
Operator.invoke
function, then this needs to be explicitly set.
import bpy
class BasicMenu(bpy.types.Menu):
bl_idname = "OBJECT_MT_select_test"
bl_label = "Select"
def draw(self, context):
layout = self.layout
layout.operator("object.select_all", text="Select/Deselect All").action = 'TOGGLE'
layout.operator("object.select_all", text="Inverse").action = 'INVERT'
layout.operator("object.select_random", text="Random")
bpy.utils.register_class(BasicMenu)
# test call to display immediately.
bpy.ops.wm.call_menu(name="OBJECT_MT_select_test")
Submenus¶
This menu demonstrates some different functions.
import bpy
class SubMenu(bpy.types.Menu):
bl_idname = "OBJECT_MT_select_submenu"
bl_label = "Select"
def draw(self, context):
layout = self.layout
layout.operator("object.select_all", text="Select/Deselect All").action = 'TOGGLE'
layout.operator("object.select_all", text="Inverse").action = 'INVERT'
layout.operator("object.select_random", text="Random")
# access this operator as a submenu
layout.operator_menu_enum("object.select_by_type", "type", text="Select All by Type...")
layout.separator()
# expand each operator option into this menu
layout.operator_enum("object.light_add", "type")
layout.separator()
# use existing memu
layout.menu("VIEW3D_MT_transform")
bpy.utils.register_class(SubMenu)
# test call to display immediately.
bpy.ops.wm.call_menu(name="OBJECT_MT_select_submenu")
Extending Menus¶
When creating menus for add-ons you can’t reference menus in Blender’s default scripts. Instead, the add-on can add menu items to existing menus.
The function menu_draw acts like Menu.draw
.
import bpy
def menu_draw(self, context):
self.layout.operator("wm.save_homefile")
bpy.types.TOPBAR_MT_file.append(menu_draw)
Preset Menus¶
Preset menus are simply a convention that uses a menu sub-class to perform the common task of managing presets.
This example shows how you can add a preset menu.
This example uses the object display options, however you can use properties defined by your own scripts too.
import bpy
from bpy.types import Operator, Menu
from bl_operators.presets import AddPresetBase
class OBJECT_MT_display_presets(Menu):
bl_label = "Object Display Presets"
preset_subdir = "object/display"
preset_operator = "script.execute_preset"
draw = Menu.draw_preset
class AddPresetObjectDisplay(AddPresetBase, Operator):
'''Add a Object Display Preset'''
bl_idname = "camera.object_display_preset_add"
bl_label = "Add Object Display Preset"
preset_menu = "OBJECT_MT_display_presets"
# variable used for all preset values
preset_defines = [
"obj = bpy.context.object"
]
# properties to store in the preset
preset_values = [
"obj.display_type",
"obj.show_bounds",
"obj.display_bounds_type",
"obj.show_name",
"obj.show_axis",
"obj.show_wire",
]
# where to store the preset
preset_subdir = "object/display"
# Display into an existing panel
def panel_func(self, context):
layout = self.layout
row = layout.row(align=True)
row.menu(OBJECT_MT_display_presets.__name__, text=OBJECT_MT_display_presets.bl_label)
row.operator(AddPresetObjectDisplay.bl_idname, text="", icon='ZOOM_IN')
row.operator(AddPresetObjectDisplay.bl_idname, text="", icon='ZOOM_OUT').remove_active = True
classes = (
OBJECT_MT_display_presets,
AddPresetObjectDisplay,
)
def register():
for cls in classes:
bpy.utils.register_class(cls)
bpy.types.OBJECT_PT_display.prepend(panel_func)
def unregister():
for cls in classes:
bpy.utils.unregister_class(cls)
bpy.types.OBJECT_PT_display.remove(panel_func)
if __name__ == "__main__":
register()
Extending the Button Context Menu¶
This example enables you to insert your own menu entry into the common right click menu that you get while hovering over a value field, color, string, etc.
To make the example work, you have to first select an object then right click on an user interface element (maybe a color in the material properties) and choose Execute Custom Action.
Executing the operator will then print all values.
import bpy
from bpy.types import Menu
def dump(obj, text):
for attr in dir(obj):
print("%r.%s = %s" % (obj, attr, getattr(obj, attr)))
class WM_OT_button_context_test(bpy.types.Operator):
"""Right click entry test"""
bl_idname = "wm.button_context_test"
bl_label = "Run Context Test"
@classmethod
def poll(cls, context):
return context.active_object is not None
def execute(self, context):
value = getattr(context, "button_pointer", None)
if value is not None:
dump(value, "button_pointer")
value = getattr(context, "button_prop", None)
if value is not None:
dump(value, "button_prop")
value = getattr(context, "button_operator", None)
if value is not None:
dump(value, "button_operator")
return {'FINISHED'}
# This class has to be exactly named like that to insert an entry in the right click menu
class WM_MT_button_context(Menu):
bl_label = "Unused"
def draw(self, context):
pass
def menu_func(self, context):
layout = self.layout
layout.separator()
layout.operator(WM_OT_button_context_test.bl_idname)
classes = (
WM_OT_button_context_test,
WM_MT_button_context,
)
def register():
for cls in classes:
bpy.utils.register_class(cls)
bpy.types.WM_MT_button_context.append(menu_func)
def unregister():
for cls in classes:
bpy.utils.unregister_class(cls)
bpy.types.WM_MT_button_context.remove(menu_func)
if __name__ == "__main__":
register()
base class — bpy_struct
-
class
bpy.types.
Menu
(bpy_struct)¶ Editor menu containing buttons
-
bl_description
¶ Type: string, default “”
-
bl_idname
¶ If this is set, the menu gets a custom ID, otherwise it takes the name of the class used to define the menu (for example, if the class name is “OBJECT_MT_hello”, and bl_idname is not set by the script, then bl_idname = “OBJECT_MT_hello”)
Type: string, default “”, (never None)
-
bl_label
¶ The menu label
Type: string, default “”, (never None)
-
bl_owner_id
¶ Type: string, default “”, (never None)
-
bl_translation_context
¶ Type: string, default “*”, (never None)
-
classmethod
poll
(context)¶ If this method returns a non-null output, then the menu can be drawn
Return type: boolean
-
draw
(context)¶ Draw UI elements into the menu UI layout
-
draw_preset
(_context)¶ Define these on the subclass: - preset_operator (string) - preset_subdir (string)
Optionally: - preset_add_operator (string) - preset_extensions (set of strings) - preset_operator_defaults (dict of keyword args)
-
path_menu
(searchpaths, operator, *, props_default=None, prop_filepath='filepath', filter_ext=None, filter_path=None, display_name=None, add_operator=None)¶ Populate a menu from a list of paths.
Parameters: - searchpaths (sequence of strings.) – Paths to scan.
- operator (string) – The operator id to use with each file.
- prop_filepath (string) – Optional operator filepath property (defaults to “filepath”).
- props_default (dict) – Properties to assign to each operator.
- filter_ext (Callable that takes a string and returns a bool.) –
Optional callback that takes the file extensions.
Returning false excludes the file from the list.
- display_name (Callable that takes a string and returns a string.) – Optional callback that takes the full path, returns the name to display.
-
classmethod
bl_rna_get_subclass
(id, default=None)¶ Parameters: id (string) – The RNA type identifier. Returns: The RNA type or default when not found. Return type: bpy.types.Struct
subclass
-
classmethod
bl_rna_get_subclass_py
(id, default=None)¶ Parameters: id (string) – The RNA type identifier. Returns: The class or default when not found. Return type: type
-
Inherited Properties
Inherited Functions