All checks were successful
Build and Test / build (pull_request) Successful in 30m3s
- Create docs/examples/example-addon/ with a complete, copy-paste-ready addon skeleton demonstrating command registration, context injection, dock panels, lifecycle hooks, and event bus subscription - Add Examples section to docs/src/SUMMARY.md - Add quick-start cross-reference in writing-an-addon.md
94 lines
2.9 KiB
Python
94 lines
2.9 KiB
Python
"""Example addon — GUI initialization.
|
|
|
|
Demonstrates the standard addon bootstrap pattern using the Kindred SDK.
|
|
Each registration step is wrapped in try/except and deferred with
|
|
QTimer.singleShot to avoid blocking the startup sequence.
|
|
"""
|
|
|
|
|
|
def _register_commands():
|
|
"""Register commands and inject into existing contexts."""
|
|
try:
|
|
from example_addon.commands import register_commands
|
|
|
|
register_commands()
|
|
except Exception as e:
|
|
import FreeCAD
|
|
|
|
FreeCAD.Console.PrintWarning(f"example-addon: command registration failed: {e}\n")
|
|
|
|
# Inject our command into an existing context's toolbar so it appears
|
|
# automatically when the user enters that context.
|
|
try:
|
|
from kindred_sdk import inject_commands
|
|
|
|
inject_commands("partdesign.body", "Part Design", ["ExampleAddon_Hello"])
|
|
except Exception as e:
|
|
import FreeCAD
|
|
|
|
FreeCAD.Console.PrintWarning(f"example-addon: context injection failed: {e}\n")
|
|
|
|
|
|
def _register_panel():
|
|
"""Register a dock panel with deferred creation."""
|
|
try:
|
|
from kindred_sdk import register_dock_panel
|
|
from example_addon.panel import create_panel
|
|
|
|
register_dock_panel(
|
|
"ExampleAddonPanel",
|
|
"Example Panel",
|
|
create_panel,
|
|
area="right",
|
|
delay_ms=2000,
|
|
)
|
|
except Exception as e:
|
|
import FreeCAD
|
|
|
|
FreeCAD.Console.PrintWarning(f"example-addon: panel registration failed: {e}\n")
|
|
|
|
|
|
def _register_lifecycle():
|
|
"""Subscribe to context lifecycle events.
|
|
|
|
Use ``on_context_enter`` / ``on_context_exit`` to react when the user
|
|
enters or leaves a specific editing context. Pass ``"*"`` to match
|
|
all contexts.
|
|
"""
|
|
try:
|
|
from kindred_sdk import on_context_enter, on_context_exit
|
|
|
|
on_context_enter("*", lambda ctx: print(f"[example-addon] entered: {ctx['id']}"))
|
|
on_context_exit("*", lambda ctx: print(f"[example-addon] exited: {ctx['id']}"))
|
|
except Exception as e:
|
|
import FreeCAD
|
|
|
|
FreeCAD.Console.PrintWarning(f"example-addon: lifecycle hooks failed: {e}\n")
|
|
|
|
|
|
def _register_events():
|
|
"""Subscribe to event bus events.
|
|
|
|
The event bus lets addons communicate without direct imports.
|
|
Use ``kindred_sdk.on(event, handler)`` to listen and
|
|
``kindred_sdk.emit(event, data)`` to publish.
|
|
"""
|
|
try:
|
|
from kindred_sdk import on
|
|
|
|
on("document.saved", lambda data: print(f"[example-addon] document saved: {data}"))
|
|
except Exception as e:
|
|
import FreeCAD
|
|
|
|
FreeCAD.Console.PrintWarning(f"example-addon: event subscription failed: {e}\n")
|
|
|
|
|
|
# Deferred initialization — stagger delays to avoid blocking startup.
|
|
# Lower delays run first; keep each step fast.
|
|
from PySide6.QtCore import QTimer
|
|
|
|
QTimer.singleShot(500, _register_commands)
|
|
QTimer.singleShot(600, _register_panel)
|
|
QTimer.singleShot(700, _register_lifecycle)
|
|
QTimer.singleShot(800, _register_events)
|