Scripting¶
PME allows for advanced customization and automation using Blender’s Python API. This article provides an overview of PME’s scripting capabilities and explains the built-in global variables and functions.
Important
Standard Command / Custom fields and menu Poll fields take one line of code. Move longer or reusable logic into an external Python file and keep a short call in the field. AI-generated code must also follow the format of its destination field.
See Writing and Running Code for field-specific syntax and execution rules. This page is the API reference for functions, variables, and arguments.
Tutorials¶
Global Variables¶
Variables available within each PME slot editor.
Variable |
Description |
|---|---|
|
Name of the active menu |
|
Name of the active slot |
|
|
|
|
|
|
|
|
|
|
|
Current UILayout object L.box().label(text="My Label")
|
|
Current Event object E.ctrl and E.shift and message_box("Ctrl+Shift Pressed")
|
|
pme.UserData instance for user data storage U.foo = "value"
U.update(foo="value1", bar="value2")
U.foo
U.get("foo", "default_value")
|
Global Functions¶
Functions available within PME slot editors. Different functions are available in Command tab and Custom tab.
Common Functions¶
- execute_script(path, **kwargs)¶
Execute an external Python script.
- Parameters:
path (str) – Script file path. Relative path (from
pie_menu_editorfolder, recommended) or absolute path.kwargs – Additional keyword arguments passed to the script.
- Returns:
return_valuefrom the script, orTrueby default.
Warning
Only place and execute scripts from trusted sources
Review contents before execution and verify in a backup or test environment if necessary
Scripts may contain operations that affect your environment, such as file operations or settings changes
Variables available in script:
kwargs,__file__,return_value, all PME global variablesExamples:
# Basic execution and return value execute_script("scripts/hello_world.py", msg="Hello World!") message_box(execute_script("scripts/get_message.py")) # scripts/hello_world.py message_box(kwargs["msg"]) # scripts/get_message.py return_value = "Hi!" # Processing with parameters # scripts/process_data.py kwargs = locals().get("kwargs", {}) result = my_function(kwargs.get("param1"), kwargs.get("param2", "default")) return_value = result # Call result = execute_script("scripts/process_data.py", param1=200, param2="Hello") # UI drawing in Custom tab # scripts/custom_ui.py msg = kwargs.get("msg", pme.context.text or "Default Message") box = L.box() box.label(text=msg, icon=pme.context.icon, icon_value=pme.context.icon_value) # Call execute_script("scripts/custom_ui.py", msg="Custom message")
- props(name=None, value=None)¶
Get or set the value of a PME Property.
- Parameters:
name (str) – Name of the property.
value – New value of the property.
- Returns:
PME property container if
nameisNone, property value if onlynameis given,Trueif setting a value.
Example:
# Get property value using string notation value = props("MyProperty") # Alternative: get property using attribute notation value = props().MyProperty # props() returns property container # Set property value using string notation props("MyProperty", value) # Alternative: set property using attribute notation props().MyProperty = value # props() returns property container
- tool_props(operator, *, tool, space_type=None, mode=None, context=None)¶
Retrieve the specified tool’s operator properties from
context.workspace. Tools and modes are unchanged. Omitted values resolve from the context at call time.- Parameters:
operator (str) – Operator identifier, such as
'sculpt.mesh_filter'.tool (str) – Expected tool identifier. Checked against the tool ID for the source editor and mode.
space_type – Editor type (
str | None).Noneusescontext.area.type.mode – Source mode (
str | None).Nonefollows the table below. An explicit value selects the source regardless of the current mode.context – Blender context.
Noneuses PME’s script context.
- Returns:
Operator properties, or
Noneif the workspace or source cannot be resolved, the tool reference is missing, or its tool ID does not match.- Return type:
bpy.types.OperatorProperties | None
- Raises:
ValueError –
space_type='NODE_EDITOR'with amodeother thanNone.
Supported editors and default modes
space_typemode=None'VIEW_3D'context.mode'IMAGE_EDITOR'context.space_data.mode'NODE_EDITOR'No mode distinction
'SEQUENCE_EDITOR'context.space_data.view_typeOmitting
modefor Image Editor or Sequencer requirescontext.space_data.typeto match the source editor. Editor types not listed in the table returnNone.Retrieval conditions
With
mode='SCULPT', properties can be retrieved even in Object Mode if the Sculpt Mode tool ID matches. Selecting another tool within the same mode changes that ID, so the function returnsNone. This does not mean the stored values were deleted from Blender.After resolving the source, an unregistered
operatorpropagates Blender’s error. Retrieve the returned RNA reference again when it is needed.Example
props = tool_props( 'sculpt.mesh_filter', tool='builtin.mesh_filter', space_type='VIEW_3D', mode='SCULPT', ) if props is not None: filter_type = props.type
- paint_settings()¶
Retrieve the context-sensitive paint settings.
- Returns:
The current paint settings or
Noneif not in a paint mode.
Example:
ps = paint_settings(); ps and L.template_ID_preview(ps, 'brush')
- find_by(collection, key, value)¶
Find the first item in
collectionwherekeyequalsvalue.- Returns:
Collection item if found, otherwise
None.
Example:
m = find_by(C.active_object.modifiers, "type", 'SUBSURF')
Command Tab Functions¶
Open menu, pie menu, popup dialog or execute a stack key, sticky key, modal operator, or macro operator by name.
- Parameters:
name (str) – Name of the menu.
slot – Index or name of the slot for Stack Key execution.
kwargs – Arguments for Modal / Macro Operators used as local variables.
- Returns:
Trueif the menu exists and is currently available. ReturnsFalsewhen the target is missing, disabled, poll-blocked, or the requested slot is not found.
Example:
# Open the menu depending on the active object's type: open_menu("Lamp Pie Menu" if C.active_object.type == 'LAMP' else "Object Pie Menu") # Call "My Stack Key" slot depending on Ctrl modifier: open_menu("My Stack Key", "Ctrl slot" if E.ctrl else "Shift slot")
Enable or disable a menu.
- tag_redraw(area=None, region=None)¶
Redraw UI areas or regions.
- close_popups()¶
Close all popup dialogs.
- Returns:
True
- overlay(text, **kwargs)¶
Draw an overlay message.
- Parameters:
text (str) – Message to display.
kwargs –
alignment: One of['TOP', 'TOP_LEFT', 'TOP_RIGHT', 'BOTTOM', 'BOTTOM_LEFT', 'BOTTOM_RIGHT']. Default is'TOP'.duration: Duration in seconds. Default is2.0.offset_x: Horizontal offset. Default is10px.offset_y: Vertical offset. Default is10px.
- Returns:
True
Example:
overlay('Hello PME!', offset_y=100, duration=1.0)
- message_box(text, icon='INFO', title='Pie Menu Editor')¶
Show a message box.
- confirm_box(message, func=None, icon='QUESTION', width=0)¶
Show a confirmation dialog from a Command slot.
- Parameters:
- Returns:
None. The function returns before the user confirms or cancels.
Put the action inside the callback. Code after
confirm_box()continues without waiting; its return value is not the user’s answer.Example 1: close the current area after confirmation:
confirm_box( "Close this area?", func=lambda ok: bpy.ops.screen.area_close() if ok else None, )
Example 2: run a PME Macro after confirmation:
confirm_box( "Run this macro?", func=lambda ok: open_menu("My Macro") if ok else None, )
Replace
My Macrowith the name of an existing, enabled Macro. Put this Command outside the target Macro: the confirmation does not pause subsequent Macro steps, and calling the same Macro would invoke it again. Both examples do nothing on cancellation. The action runs in the context available to the callback; normal operator and menu poll requirements apply. Open only one confirmation dialog at a time, as callbacks are shared between dialogs.
Custom Tab Functions¶
Draw a popup dialog inside another popup dialog or a pie menu.
- Parameters:
- Returns:
Trueif the menu exists and is currently available. ReturnsFalsewithout drawing when the target is missing, disabled, or poll-blocked.
- operator(layout, idname, text='', icon='NONE', emboss=True, icon_value=0, **kwargs)¶
Similar to
UILayout.operator(), but allows filling operator properties.- Parameters:
- Returns:
OperatorPropertiesobject.
Example:
operator(L, "wm.context_set_int", "Material Slot 1", data_path="active_object.active_material_index", value=0) # Same as: # op = L.operator("wm.context_set_int", text="Material Slot 1") # op.data_path = "active_object.active_material_index" # op.value = 0
- custom_icon(filename)¶
Get the integer value associated with a custom icon.
- Parameters:
filename (str) – Icon filename without extension, located in
pie_menu_editor/icons/.- Returns:
The integer value of the custom icon.
Example:
L.label(text="My Custom Icon", icon_value=custom_icon("p1"))
- panel(pt, frame=True, header=True, expand=None, area=None, root=False, poll=True, layout=None)¶
Draws a panel by its ID.
- Parameters:
pt (Union[str, Type]) – Panel class or panel class name string. If string, the corresponding class is searched from
bpy.types.frame (bool) – Controls whether to frame the panel. If
True, useslayout.box(). IfFalse, useslayout.column().header (bool) – Controls panel header display style.
expand (Optional[bool]) – Controls initial expansion state of panel.
True: start expanded,False: start collapsed,None: retain previous state.area (Optional[str]) –
Area.typethe panel should be drawn against (e.g.'VIEW_3D','PROPERTIES'). Useful when drawing an editor-specific panel (such asVIEW3D_PT_*) from a popup dialog or a different editor, so the panel’spoll/drawcan resolve the expectedspace_data. UseNoneor'CURRENT'to keep the current context.root (bool) – If
True, draws the panel directly on the currentpme.context.layoutwithout wrapping it in an extrabox()/column(). WhenTrue, theframeandlayoutparameters are ignored. Use this to avoid an extra layer of nesting in tightly controlled layouts.poll (bool) – Controls whether to execute the panel’s
pollmethod. IfTrue, checks the panel’s display conditions.layout (Optional[Any]) – Specify a custom layout.
- Returns:
True
- Return type:
Example:
panel("MATERIAL_PT_context_material", True, True, True) # Change panel size L.scale_x = 0.8; panel("USERPREF_PT_interface", layout=L.box()) # Draw a 3D View panel from a popup dialog panel("VIEW3D_PT_tools_meshedit_options", area='VIEW_3D') # Draw without an extra wrapping box/column panel("MATERIAL_PT_context_material", root=True)
Auto-run Scripts¶
PME can execute Python scripts automatically when Blender starts.
autorun uses exec(...) in PME’s execution namespace rather than ordinary Python module imports.
It searches two locations:
System: bundled
assets/scripts/autorunUser:
scripts/autorununder File Locations
Startup scans the system location first, then the user location. The user location accepts:
Direct
.pyfilesFolders containing scripts
Symbolic links
Note
pme and bpy are already injected as globals in autorun scripts.
Scripts intended for PME’s autorun or execute_script() normally do not need
import pme or import bpy. Add ordinary imports as needed if the file
must also run independently in Blender’s Text Editor or as a Python module.
Warning
Only place and execute scripts from trusted sources.
Review their contents; use backups or a test environment when appropriate.
Scripts may change files, settings, or other parts of your environment.
Add Custom Global Functions¶
A common use of autorun is to register helper functions at startup for reuse in Command and Custom:
Place a
.pyfile inscripts/autorununder File Locations.Register the functions with
pme.context.add_global().
Minimal example:
def hello_world():
message_box("Hello World")
pme.context.add_global("hello", hello_world)
The registered hello() is available in:
Command
Custom
External files run with
execute_script()
A more practical example:
def active_object_name(default="No Active Object"):
obj = C.active_object
return obj.name if obj else default
def show_active_object_name():
overlay(active_object_name())
return True
pme.context.add_global("active_object_name", active_object_name)
pme.context.add_global("ao_name", active_object_name) # Register a short alias
pme.context.add_global("show_active_object_name", show_active_object_name)
After registration, call these functions from PME scripts:
# Command tab
show_active_object_name()
# Custom tab
L.label(text=ao_name(), icon='OBJECT_DATA')
See also
Boot Options for external scripts that need
import pme.
PME Components¶
PME maintains a global context that provides access to commonly used functions, variables, and user-defined additions. This context is accessible through two main interfaces:
- class pme.context¶
- globals: dict¶
Access PME’s global context dictionary. Contains:
Built-in shortcuts (
C,D,O,L, etc.)Registered custom functions and values
User data storage (
U)
from pie_menu_editor import pme # Access globals from external scripts g = pme.context.globals props = g.get('props') user_data = g.get('U')
- add_global(key, value)¶
Register a custom function or value in the global context.
- Parameters:
key (str) – Name for accessing the item
value – Function or value to register
- Return type:
None
# Register a function def my_tool(): bpy.ops.mesh.select_all(action='TOGGLE') pme.context.add_global("toggle_select", my_tool) # Register a constant pme.context.add_global("MAX_ITEMS", 10) # Access from PME menus via Command tab: # toggle_select() # MAX_ITEMS
- class pme.UserData¶
Flexible storage for user-defined data that persists during the Blender session.
- get(name, default=None)¶
Get a stored value.
- Parameters:
name (str) – Data key
default – Value to return if key doesn’t exist
- Returns:
Stored value or default
- update(**kwargs)¶
Update multiple values at once.
U = pme.context.globals['U'] # Get UserData instance U.update(tool_state="active", count=5) print(U.tool_state) # "active"