跳转到内容

编写工具插件

本教程演示如何创建一个 Python 工具,使其带着自动生成的选项对话框出现在 LinkCAD 的菜单系统中。

工具框架

一个工具插件由以下部分组成:

  1. 一个用 @tool() 装饰并继承 Tool 的类
  2. 定义 UI 对话框的 Option 类属性
  3. 一个实现逻辑并返回结果字典的 run() 方法

传给 run()drawing 是一个 linkcad.v1.db.Drawing——由应用程序拥有的活动数据库。请通过数据库 API 读取它:drawing.cellsdrawing.layerscell.shapes 等。

示例:图层统计

在插件目录中创建文件 layer_stats.py

from typing import Any, Dict
from linkcad.v1.plugin import tool, Tool, Option
@tool(
name="Layer Statistics",
menu="Tools/Analysis",
tooltip="Show shape count per layer",
)
class LayerStats(Tool):
include_empty = Option.boolean(
"Include empty layers",
default=False,
tooltip="Show layers with zero shapes",
)
def run(self, drawing) -> Dict[str, Any]:
counts = {layer.name: 0 for layer in drawing.layers}
# One pass over the drawing, sorting each shape into its layer's tally.
# Walking the drawing once per layer would re-read every shape as many
# times as there are layers.
for cell in drawing.cells:
for shape in cell.shapes:
if shape.layer is not None:
counts[shape.layer.name] = counts.get(shape.layer.name, 0) + 1
if not self.include_empty:
counts = {name: n for name, n in counts.items() if n}
return {
"layers": counts,
"summary": f"{len(counts)} layers, {sum(counts.values())} shapes",
}
def format_result(self, result: Dict[str, Any]) -> str:
lines = [f"{name}: {n} shapes" for name, n in result["layers"].items()]
lines += ["", result["summary"]]
return "\n".join(lines)

工作原理

  1. @tool() 将该类注册为 LinkCAD 工具
  2. name 显示在菜单中,menu 设置菜单路径
  3. Option.boolean(...) 在自动生成的对话框中创建一个复选框
  4. 用户在对话框中点击“确定”时调用 run(),它返回结果字典
  5. format_result() 将该字典转换为 LinkCAD 显示的文本。若需要比默认输出更好的呈现,请重写它

修改图纸

run() 执行期间,框架持有读锁。要写入,请打开事务——成功时提交,抛出异常时回滚,并在撤销历史中作为一个条目出现:

from linkcad.v1.db import Transaction
def run(self, drawing):
with Transaction(drawing, "Add Frame"):
frame = drawing.add_cell("FRAME")
layer = drawing.add_layer("OUTLINE")
b = drawing.main_cell.bounds
frame.add_polyline(
layer,
[(b.min_x, b.min_y), (b.max_x, b.min_y),
(b.max_x, b.max_y), (b.min_x, b.max_y)],
closed=True,
)
return {"summary": "Added FRAME"}

选项类型

工厂方法UI 控件示例
Option.integer()微调框Option.integer("Count", default=1, min=0, max=100)
Option.real()小数微调框Option.real("Scale", default=1.0, decimals=4)
Option.boolean()复选框Option.boolean("Enable", default=True)
Option.string()文本框Option.string("Name", default="output")
Option.choice()下拉列表Option.choice("Mode", choices=["Fast", "Precise"])
Option.path()文件选择器Option.path("Output", file_filter="*.csv")
Option.color()颜色选择器Option.color("Fill", default="#FF0000")
Option.table()可编辑网格参见面板拼版
Option.cell_choice()单元下拉列表Option.cell_choice("Target Cell")

条件选项

使用 enabled_when 动态启用或禁用选项:

class MyTool(Tool):
mode = Option.choice("Mode", choices=["Simple", "Advanced"])
threshold = Option.real(
"Threshold",
default=0.5,
enabled_when=lambda self: self.mode == "Advanced",
)

只有当 mode 为 “Advanced” 时,threshold 字段才可用。

键盘快捷键

@tool(
name="My Tool",
menu="Tools/Custom",
shortcut="Ctrl+Shift+M",
)
class MyTool(Tool):
...

后续步骤