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

menu

Name of the active menu

slot

Name of the active slot

C

bpy.context

D

bpy.data

O

bpy.ops

T

bpy.types

P

bpy.props

L

Current UILayout object

L.box().label(text="My Label")

E

Current Event object

E.ctrl and E.shift and message_box("Ctrl+Shift Pressed")

U

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_editor folder, recommended) or absolute path.

  • kwargs – Additional keyword arguments passed to the script.

Returns:

return_value from the script, or True by 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 variables

Examples:

# 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 name is None, property value if only name is given, True if 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). None uses context.area.type.

  • mode – Source mode (str | None). None follows the table below. An explicit value selects the source regardless of the current mode.

  • context – Blender context. None uses PME’s script context.

Returns:

Operator properties, or None if 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:

ValueErrorspace_type='NODE_EDITOR' with a mode other than None.

Supported editors and default modes

space_type

mode=None

'VIEW_3D'

context.mode

'IMAGE_EDITOR'

context.space_data.mode

'NODE_EDITOR'

No mode distinction

'SEQUENCE_EDITOR'

context.space_data.view_type

Omitting mode for Image Editor or Sequencer requires context.space_data.type to match the source editor. Editor types not listed in the table return None.

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 returns None. This does not mean the stored values were deleted from Blender.

After resolving the source, an unregistered operator propagates 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 None if 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 collection where key equals value.

Returns:

Collection item if found, otherwise None.

Example:

m = find_by(C.active_object.modifiers, "type", 'SUBSURF')
setattr(object, name, value)

Same as Python’s built-in setattr(), but returns True after setting.

Returns:

True

Command Tab Functions

open_menu(name, slot=None, **kwargs)

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:

True if the menu exists and is currently available. Returns False when 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")
toggle_menu(name, value=None)

Enable or disable a menu.

Parameters:
  • name (str) – Name of the menu.

  • value (bool) – True to enable, False to disable, None to toggle.

Returns:

True if the menu exists, False otherwise.

tag_redraw(area=None, region=None)

Redraw UI areas or regions.

Parameters:
  • area (str) – The Area.type to redraw. Redraw all areas if None.

  • region (str) – The Region.type to redraw. Redraw all regions if None.

Returns:

True

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 is 2.0 .

    • offset_x: Horizontal offset. Default is 10 px.

    • offset_y: Vertical offset. Default is 10 px.

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.

Parameters:
  • text (str) – Message to display.

  • icon (str) – Icon name (e.g. ‘INFO’, ‘ERROR’, ‘QUESTION’, etc.).

  • title (str) – Window title.

Returns:

True

confirm_box(message, func=None, icon='QUESTION', width=0)

Show a confirmation dialog from a Command slot.

Parameters:
  • message (str) – Message to display.

  • func – Optional callback accepting one boolean argument: True on OK, False on cancellation.

  • icon (str) – Blender icon name. Default is 'QUESTION'.

  • width (int) – Dialog width in pixels. 0 uses Blender’s default width.

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 Macro with 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.

input_box(func=None, prop=None)

Show an input box.

Parameters:
  • func – Function to call with the input value.

  • prop (str) – Path to the property to edit.

Returns:

True

Example:

# Rename object:
input_box(prop="C.active_object.name")

# Display input value:
input_box(func=lambda value: overlay(value))

Custom Tab Functions

draw_menu(name, frame=True, dx=0, dy=0)

Draw a popup dialog inside another popup dialog or a pie menu.

Parameters:
  • name (str) – Name of the menu (popup dialog).

  • frame (bool) – Whether to draw a frame.

  • dx (int) – Horizontal offset.

  • dy (int) – Vertical offset.

Returns:

True if the menu exists and is currently available. Returns False without 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:
  • layout – A UILayout instance.

  • idname (str) – Identifier of the operator.

Returns:

OperatorProperties object.

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, uses layout.box(). If False, uses layout.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.type the panel should be drawn against (e.g. 'VIEW_3D', 'PROPERTIES'). Useful when drawing an editor-specific panel (such as VIEW3D_PT_*) from a popup dialog or a different editor, so the panel’s poll / draw can resolve the expected space_data. Use None or 'CURRENT' to keep the current context.

  • root (bool) – If True, draws the panel directly on the current pme.context.layout without wrapping it in an extra box() / column(). When True, the frame and layout parameters are ignored. Use this to avoid an extra layer of nesting in tightly controlled layouts.

  • poll (bool) – Controls whether to execute the panel’s poll method. If True, checks the panel’s display conditions.

  • layout (Optional[Any]) – Specify a custom layout.

Returns:

True

Return type:

bool

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/autorun

  • User: scripts/autorun under File Locations

Startup scans the system location first, then the user location. The user location accepts:

  • Direct .py files

  • Folders 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:

  1. Place a .py file in scripts/autorun under File Locations.

  2. 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

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"