跳转到内容

@tool() 装饰器

把类注册为 LinkCAD 工具,使其带着自动生成的选项对话框出现在应用程序菜单中。

签名

@tool(
name: str,
menu: str,
tooltip: str = "",
shortcut: str = "",
icon: str = "",
requires_drawing: bool = True,
)
class MyTool(Tool):
...

参数

参数类型默认值说明
namestr必填菜单中的显示名称
menustr必填菜单路径(用 / 表示子菜单),例如 "Tools/Analysis"
tooltipstr""悬停时显示的提示
shortcutstr""键盘快捷键(例如 "Ctrl+Shift+M"
iconstr""相对于 res/ 的图标文件名
requires_drawingboolTrue未加载图纸时是否禁用该工具

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)