DocumentationDocumentation
User guide/Actions, state, and events

Call Python from the interface

Connect user interactions to add-on actions with clear arguments, results, and failure feedback.

Use the starter add-on's binding location

This guide builds on Starter tutorial. Python has imported bpy and _get_plugin binds on demand. The example adds a read-only action that looks up object type by name without changing the scene. Replace my_addon with your actual identity on both sides.

Define the handler in the module

Add-on logic module
python
def _inspect_object(payload, context):
    name = payload.get("name") if isinstance(payload, dict) else None
    if not isinstance(name, str) or not name.strip():
        return {"ok": False, "message": "请输入对象名称。"}
    obj = bpy.context.scene.objects.get(name)
    if obj is None:
        return {"ok": False, "message": "当前场景没有这个对象。"}
    return {"ok": True, "name": obj.name, "type": obj.type}

Register once after bind succeeds in _get_plugin. Do not register on every page click or overwrite existing actions.

Add this line after binding
python
_plugin.bridge().action("plugin.my_addon.inspect_object", _inspect_object)

Send requests and show results from the button

Add these controls to the existing page shell and save JavaScript as inspect.js beside it. Keep the existing close and drag scripts.

Page controls
html
<label>Object name <input id="object-name" type="text"></label>
<button id="inspect" type="button">Read object</button>
<p id="inspect-result" role="status"></p>
<script src="inspect.js"></script>
inspect.js
javascript
const button = document.getElementById("inspect");
const input = document.getElementById("object-name");
const output = document.getElementById("inspect-result");
button.addEventListener("click", async () => {
  button.disabled = true;
  try {
    const result = await window.acquireNexusWebUI().action.call(
      "plugin.my_addon.inspect_object", { name: input.value }
    );
    output.textContent = result.ok
      ? `${result.name}:${result.type}` : result.message;
  } catch (error) {
    output.textContent = `读取失败:${error.message || String(error)}`;
  } finally {
    button.disabled = false;
  }
});

The add-on validates arguments and execution conditions

context supplies origin, user-initiation information, and window identity; it is not bpy.context. Before changing a scene, check mode, target existence, and application permissions/selection. Do not trust page-provided names, values, or success flags as facts.

Return only JSON-compatible data. Explain application failures; do not swallow unexpected exceptions or fabricate success. Catch page-side rejections and re-enable the button.

Connect modifying actions to state refresh

If an action changes published state, declare invalidates=('plugin.my_addon.objects',) when registering, or manually invalidate at the actual change notification. Declare that state with your own field schema first. See Keep the interface in sync with data.

This read-only action needs neither refresh nor undo. For undoable transforms, see Value dragging and undo. Ordinary actions are not automatic undo transactions.

Verify three inputs

  • An existing scene object name displays its actual name and type.
  • A missing or blank name explains the issue and leaves the button reusable.
  • A temporarily mismatched action name should display a call failure. Restore the correct name before delivery.

Include the script in the packaging manifest. An ordinary browser has no Blender bridge and cannot verify this read.

Based on the actions/state guide, starter template, and public page API.

Back to User guide · All topics