# KCSDK Python API Reference The `kcsdk` module provides Python access to the Kindred Create addon SDK. It is built with pybind11 and installed alongside the Create module. The `kindred_sdk` package (`mods/sdk/kindred_sdk/`) provides convenience wrappers that route through `kcsdk` when available, falling back to legacy `FreeCADGui.*` bindings. Addons should prefer `kindred_sdk` over importing `kcsdk` directly. ```python import kcsdk # C++ bindings (low-level) import kindred_sdk # Python wrappers (recommended) ``` ## Module constants | Name | Value | Description | |------|-------|-------------| | `API_VERSION_MAJOR` | `1` | KCSDK API major version | ## Enums ### DockArea Dock widget placement area. Values match `Qt::DockWidgetArea`. | Value | Integer | Description | |-------|---------|-------------| | `DockArea.Left` | 1 | Left dock area | | `DockArea.Right` | 2 | Right dock area | | `DockArea.Top` | 4 | Top dock area | | `DockArea.Bottom` | 8 | Bottom dock area | ### PanelPersistence Whether a dock panel's visibility survives application restarts. | Value | Description | |-------|-------------| | `PanelPersistence.Session` | Visible until application close | | `PanelPersistence.Persistent` | Saved to preferences and restored on next launch | ## Editing Context API These functions manage the context-aware UI system. Contexts control which toolbars are visible based on the current editing state. ### register_context(id, label, color, toolbars, match, priority=50) Register an editing context. | Parameter | Type | Description | |-----------|------|-------------| | `id` | `str` | Unique identifier (e.g. `"myaddon.edit"`) | | `label` | `str` | Display label template. Supports `{name}` placeholder | | `color` | `str` | Hex color for breadcrumb (e.g. `"#f38ba8"`) | | `toolbars` | `list[str]` | Toolbar names to show when active | | `match` | `callable` | Zero-arg callable returning `True` when active | | `priority` | `int` | Higher values checked first. Default 50 | ```python kcsdk.register_context( "myworkbench.edit", "Editing {name}", "#89b4fa", ["MyToolbar", "StandardViews"], lambda: is_my_object_in_edit(), priority=60, ) ``` ### unregister_context(id) Remove a previously registered editing context. ### register_overlay(id, toolbars, match) Register an editing overlay. Overlays add toolbars to whatever context is currently active when `match()` returns `True`. | Parameter | Type | Description | |-----------|------|-------------| | `id` | `str` | Unique overlay identifier | | `toolbars` | `list[str]` | Toolbar names to append | | `match` | `callable` | Zero-arg callable returning `True` when the overlay applies | ### unregister_overlay(id) Remove a previously registered overlay. ### inject_commands(context_id, toolbar_name, commands) Inject additional commands into an existing context's toolbar. | Parameter | Type | Description | |-----------|------|-------------| | `context_id` | `str` | Target context identifier | | `toolbar_name` | `str` | Toolbar within that context | | `commands` | `list[str]` | Command names to add | ```python kcsdk.inject_commands("partdesign.body", "PartDesign", ["MyAddon_CustomFeature"]) ``` ### current_context() Return the current editing context as a dict, or `None`. Keys: `id`, `label`, `color`, `toolbars`, `breadcrumb`, `breadcrumbColors`. ### refresh() Force re-resolution of the editing context. ## Panel Provider API These functions manage dock panel registration. Panels are created through the `IPanelProvider` interface and managed by `DockWindowManager`. ### IPanelProvider Abstract base class for dock panel providers. Subclass in Python to create custom panels. Three methods must be implemented: ```python class MyPanel(kcsdk.IPanelProvider): def id(self): return "myaddon.panel" def title(self): return "My Panel" def create_widget(self): from PySide import QtWidgets label = QtWidgets.QLabel("Hello from my addon") return label ``` Optional methods with defaults: | Method | Return type | Default | Description | |--------|-------------|---------|-------------| | `preferred_area()` | `DockArea` | `DockArea.Right` | Dock placement area | | `persistence()` | `PanelPersistence` | `PanelPersistence.Session` | Visibility persistence | | `context_affinity()` | `str` | `""` (always visible) | Only show in named context | ```python class SidePanel(kcsdk.IPanelProvider): def id(self): return "myaddon.side" def title(self): return "Side Panel" def create_widget(self): from PySide import QtWidgets return QtWidgets.QTreeWidget() def preferred_area(self): return kcsdk.DockArea.Left def context_affinity(self): return "partdesign.body" # only visible in PartDesign body context ``` ### register_panel(provider) Register a dock panel provider. The provider is stored in the registry until `create_panel()` is called to instantiate the actual dock widget. | Parameter | Type | Description | |-----------|------|-------------| | `provider` | `IPanelProvider` | Panel provider instance | ### unregister_panel(id) Remove a registered panel provider and destroy its dock widget if created. ### create_panel(id) Instantiate the dock widget for a registered panel. Calls the provider's `create_widget()` once and embeds the result in a `QDockWidget` via `DockWindowManager`. Skips silently if the panel already exists. ### create_all_panels() Instantiate dock widgets for all registered panels. ### registered_panels() Return IDs of all registered panel providers as `list[str]`. ### available() Return names of all registered providers (across all provider types) as `list[str]`. ## `kindred_sdk` Convenience Wrappers The `kindred_sdk` Python package wraps the `kcsdk` C++ module with input validation, error handling, and fallback to legacy APIs. ### kindred_sdk.register_dock_panel(object_name, title, widget_factory, area="right", delay_ms=0) High-level dock panel registration. Creates an anonymous `IPanelProvider` internally and schedules creation via `QTimer`. | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `object_name` | `str` | | Qt object name (used as panel ID) | | `title` | `str` | | Dock widget title | | `widget_factory` | `callable` | | Zero-arg callable returning a `QWidget` | | `area` | `str` | `"right"` | `"left"`, `"right"`, `"top"`, or `"bottom"` | | `delay_ms` | `int` | `0` | Defer creation by this many milliseconds | ```python from kindred_sdk import register_dock_panel from PySide import QtWidgets register_dock_panel( "MyAddonPanel", "My Addon", lambda: QtWidgets.QLabel("Hello"), area="left", delay_ms=2000, ) ``` ### Other `kindred_sdk` Wrappers These mirror the `kcsdk` functions with added type validation and try/except error handling: | Function | Maps to | |----------|---------| | `kindred_sdk.register_context()` | `kcsdk.register_context()` | | `kindred_sdk.unregister_context()` | `kcsdk.unregister_context()` | | `kindred_sdk.register_overlay()` | `kcsdk.register_overlay()` | | `kindred_sdk.unregister_overlay()` | `kcsdk.unregister_overlay()` | | `kindred_sdk.inject_commands()` | `kcsdk.inject_commands()` | | `kindred_sdk.current_context()` | `kcsdk.current_context()` | | `kindred_sdk.refresh_context()` | `kcsdk.refresh()` | | `kindred_sdk.register_origin()` | `FreeCADGui.addOrigin()` | | `kindred_sdk.unregister_origin()` | `FreeCADGui.removeOrigin()` | | `kindred_sdk.get_theme_tokens()` | YAML palette lookup | | `kindred_sdk.load_palette()` | `Palette` object from YAML | | `kindred_sdk.create_version()` | Kindred Create version string | | `kindred_sdk.freecad_version()` | FreeCAD version tuple | ## Architecture ``` Python Addon Code | kindred_sdk (mods/sdk/) <- convenience wrappers + validation | kcsdk.so (pybind11 module) <- C++ API bindings | libKCSDK.so (C++ shared library) <- SDKRegistry + provider interfaces | FreeCADGui (EditingContextResolver, DockWindowManager, OriginManager, ...) ``` When `kcsdk` is not available (console mode, build not installed), `kindred_sdk` falls back to legacy `FreeCADGui.*` Python bindings. ## Related - [Writing an Addon](../development/writing-an-addon.md) - [Package.xml Schema Extensions](../development/package-xml-schema.md) - [Create Module Bootstrap](./create-module-bootstrap.md)