Der Dekorator @tool()
Registriert eine Klasse als LinkCAD-Tool, das mit einem automatisch generierten Optionsdialog im Anwendungsmenü erscheint.
Signatur
@tool( name: str, menu: str, tooltip: str = "", shortcut: str = "", icon: str = "", requires_drawing: bool = True,)class MyTool(Tool): ...Parameter
| Parameter | Typ | Standard | Beschreibung |
|---|---|---|---|
name | str | erforderlich | Anzeigename im Menü |
menu | str | erforderlich | Menüpfad (mit / für Untermenüs), z. B. "Tools/Analysis" |
tooltip | str | "" | Tooltip beim Überfahren |
shortcut | str | "" | Tastenkürzel (z. B. "Ctrl+Shift+M") |
icon | str | "" | Symboldateiname, relativ zu res/ |
requires_drawing | bool | True | Ob das Tool ohne geladene Zeichnung deaktiviert wird |
Basisklasse Tool
Alle Tool-Plugins müssen Tool erweitern und run() implementieren:
class Tool: def run(self, drawing) -> dict: """Override to implement the tool logic. Return a result dictionary.""" ...
def format_result(self, result: dict) -> str: """Override to control how the result is displayed.""" ...Das Argument drawing ist ein linkcad.v1.db.Drawing — die aktive Datenbank, die der Anwendung gehört; zerstören Sie sie also nie. Bei requires_drawing=False kann sie None sein.
run() gibt ein Ergebnis-Dictionary zurück. Die Standardimplementierung von format_result() gibt result["summary"] aus, sofern vorhanden — nehmen Sie einen solchen Schlüssel also auf. Überschreiben Sie format_result() für reichhaltigere Ausgaben.
Während run() läuft, hält das Framework eine Lesesperre. Kapseln Sie Änderungen in eine Transaction, damit sie rückgängig gemacht werden können.
ToolInfo
Der Dekorator erzeugt ein ToolInfo-Objekt an der Klasse:
| Feld | Beschreibung |
|---|---|
name | Anzeigename des Tools |
menu | Menüpfad |
tooltip | Tooltip-Text |
shortcut | Tastenkürzel |
icon | Symboldateiname |
requires_drawing | Ob eine Zeichnung erforderlich ist |
options | Die aus der Klasse gesammelten Option-Attribute |
Menüpfad
Der Parameter menu legt fest, wo das Tool im Menü von LinkCAD erscheint:
"Edit/Analyze" → Edit → Analyze → <tool name>"Tools/Analysis" → Tools → Analysis → <tool name>"Tools/Drawing/Custom" → Tools → Drawing → Custom → <tool name>Vollständiges Beispiel
from typing import Any, Dict
from linkcad.v1.plugin import tool, Tool, Option
@tool( name="Shape Counter", menu="Tools/Analysis", tooltip="Count shapes per layer", shortcut="Ctrl+Shift+C", requires_drawing=True,)class ShapeCounter(Tool): closed_only = Option.boolean("Closed shapes only", default=False)
def run(self, drawing) -> Dict[str, Any]: counts: Dict[str, int] = {} for cell in drawing.cells: for shape in cell.shapes: if self.closed_only and not shape.closed: continue layer = shape.layer if layer is not None: counts[layer.name] = counts.get(layer.name, 0) + 1
return { "layers": counts, "summary": f"{sum(counts.values())} shapes on {len(counts)} layers", }
def format_result(self, result: Dict[str, Any]) -> str: lines = [f"{name}: {n}" for name, n in sorted(result["layers"].items())] lines += ["", result["summary"]] return "\n".join(lines)