@tool() 装饰器
把类注册为 LinkCAD 工具,使其带着自动生成的选项对话框出现在应用程序菜单中。
签名
@tool( name: str, menu: str, tooltip: str = "", shortcut: str = "", icon: str = "", requires_drawing: bool = True,)class MyTool(Tool): ...参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
name | str | 必填 | 菜单中的显示名称 |
menu | str | 必填 | 菜单路径(用 / 表示子菜单),例如 "Tools/Analysis" |
tooltip | str | "" | 悬停时显示的提示 |
shortcut | str | "" | 键盘快捷键(例如 "Ctrl+Shift+M") |
icon | str | "" | 相对于 res/ 的图标文件名 |
requires_drawing | bool | True | 未加载图纸时是否禁用该工具 |
Tool 基类
所有工具插件都必须继承 Tool 并实现 run():
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.""" ...drawing 参数是一个 linkcad.v1.db.Drawing——由应用程序拥有的活动数据库,因此切勿销毁它。当 requires_drawing=False 时它可能为 None。
run() 返回一个结果字典。默认的 format_result() 会打印 result["summary"](若存在),因此请包含该键。需要更丰富的展示时请重写 format_result()。
run() 执行期间,框架持有读锁。要让修改可撤销,请用 Transaction 包裹它们。
ToolInfo
装饰器会在类上创建一个 ToolInfo 对象:
| 字段 | 说明 |
|---|---|
name | 工具显示名称 |
menu | 菜单路径 |
tooltip | 提示文本 |
shortcut | 键盘快捷键 |
icon | 图标文件名 |
requires_drawing | 是否需要图纸 |
options | 从类中收集到的 Option 属性 |
菜单路径
menu 参数决定工具出现在 LinkCAD 菜单中的位置:
"Edit/Analyze" → Edit → Analyze → <tool name>"Tools/Analysis" → Tools → Analysis → <tool name>"Tools/Drawing/Custom" → Tools → Drawing → Custom → <tool name>完整示例
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)