建模语言¶
自2.0版本起,Gaphor开始支持建模语言概念。这一特性使得建模语言的开发能够独立于Gaphor核心应用程序进行。
UML始终是Gaphor的核心建模语言。当前版本还新增支持SysML子集、RAAML及C4模型。
在Gaphor中,建模语言通过实现gaphor.abc.ModelingLanguage抽象基类的类来定义。该建模语言需注册为gaphor.modelinglanguages入口点。
ModelingLanguage接口设计极为精简,主要提供元素、工具箱及图表类型的查询功能。但建模语言的职责远不止于此,部分功能需通过向通用函数注册处理器来实现。
但让我们循序渐进地探讨:建模语言的实现具体能提供哪些功能?
ModelingLanguage实例主要提供三大功能:
数据模型(元素)与图表项
图表类型
工具箱定义
其他功能可以通过向相应的通用功能添加处理程序(Handler)来扩展。
连接器允许图表元素相互连接
格式化/解析模型元素与文本格式的相互转换
复制/粘贴 适用于非简单元素复制的情况,例如涉及多个元素时
分组允许元素相互嵌套
拖放允许将元素从树状视图拖拽至图表中
自动清理规则 保持模型一致性
建模语言还可以提供新的 UI 组件。这些组件不会在导入建模语言包时直接加载,而应通过 gaphor.modules 入口点导入。
编辑器页面显示在右侧可折叠面板中
特殊图表交互
建模语言¶
- class gaphor.abc.ModelingLanguage[源代码]¶
模型提供者(Model Provider)是一种特殊服务,它为UML、SysML、RAAML等模型实现提供入口点。
- abstract property diagram_types: Iterable[DiagramType]¶
迭代图表类型。
- abstract property element_types: Iterable[ElementCreateInfo]¶
迭代元素类型。
- abstractmethod lookup_element(name: str, ns: str | None = None) type[Base] | None[源代码]¶
通过(类)名称查询模型元素类型。
可提供命名空间,该设置将限定模型仅能从特定建模语言加载。
- abstract property toolbox_definition: ToolboxDefinition¶
获取工具箱结构。
根据约定,包含建模语言的包应设置__modeling_language__属性,其属性值需与入口点中的建模语言名称保持一致。
示例说明:
文件mytool/mylang/__init__.py中包含以下条目:
__modeling_language__ = "MyLang"
pyproject.toml 文件中包含以下入口点配置:
[project.entry-points."gaphor.modelinglanguages"]
"MyLang" = "mytool.mylang.modelinglanguage:MyLangModelingLanguage"
连接器¶
连接器用于实现元素间的相互连接。
连接器应遵循ConnectorProtocol协议规范。通常建议继承BaseConnector基类实现。
- class gaphor.diagram.connectors.BaseConnector(element: Presentation[Base], line: Presentation[Base])[源代码]¶
Gaphor 图表项连接适配器。
线段项
line通过连接柄与可连接项element建立关联。- 参数:
line -- 连接项
element -- 可连接项
根据规范,适配器需按(元素,线段)的顺序进行注册。
格式化与解析¶
模型元素可格式化为简单文本表示形式(例如在模型浏览器中使用)。请注意,此非模型元素的完整序列化。
某些情况下,将文本解析回对象十分实用。该功能常用于编辑类的属性和操作时。
并非所有format()方法都需要对应的parse()函数。
复制和粘贴¶
对于简单项(即单个图表项对应单个模型元素的情况),复制粘贴功能可开箱即用。该功能通过调用元素的load()和save()方法,确保复制所有相关数据。
某些情况下,图表项需要多个模型元素协同工作。例如关联(Association)元素就需要两个关联端(association ends)才能正常运作。
针对这些特定情况,您需要自行实现复制粘贴功能。具体需要创建两个函数:一个处理复制操作,另一个处理粘贴操作。
- gaphor.diagram.copypaste.copy(obj: Base | Iterable) Iterator[tuple[Id, Opaque]]¶
创建元素(或元素列表)的副本。返回类型应具有独特性,以便
paste()函数能正确分发。复制函数通常仅复制元素及其必需关联元素,例如关联(Association)必须包含两个关联端。
- gaphor.diagram.copypaste.paste(copy_data: Opaque, diagram: Diagram, lookup: Callable[[str], Base | None]) Iterator[Base]¶
粘贴先前复制的数据。根据
copy()函数中创建的数据类型,尝试复制被拷贝的元素。返回新创建的项或元素。
Gaphor 提供以下便捷功能:
- gaphor.diagram.copypaste.copy_full(items: Collection[Base], lookup: Callable[[Id], Base | None] | None = None) CopyData:¶
复制
items。该操作使用lookup函数查询所属元素(这些元素在模型浏览器中显示为子节点)。
分组¶
分组操作通过将一个元素拖拽到另一个元素上来实现,可在图表或树状视图中进行。
- gaphor.diagram.group.owner(element: Base) Base | RootType | None¶
返回
element的所有者。所有者可能为Root(表示该元素应置于所属关系层级的根节点)。若返回None,则表示该元素没有所有者。
- gaphor.diagram.group.group(parent: Base, element: Base) bool¶
将元素归组到父元素中。分组可基于所属关系(Ownership)实现,但也支持其他分组类型。
拖放¶
拖放操作通过将元素从树状视图拖拽至图表中完成。这是使用现有模型元素快速扩展图表的便捷方式。
此外,也可将展示项(Presentation item)拖放至其他元素上方。
- gaphor.diagram.drop.drop(element: Base | Presentation, diagram: Diagram | Presentation, x: float, y: float) Presentation | None¶
拖放功能会为元素在图表中创建新的展示项(若该元素尚未被展示)。对于关联关系,只有当被连接的两个元素都存在于同一图表中时,拖放操作才会生效。
分组(Grouping) 用于关联模型元素,而 拖放(Dropping) 则用于在图表中的目标项上创建和定位展示元素。
自动模型清理¶
Gaphor 致力于保持模型与图表之间的同步。
通过一个小型调度函数来判断模型元素是否可被移除。
属性编辑器页面¶
编辑器页面由多个代码片段构建而成。例如:几乎每个元素都包含名称属性,因此会有一个专门的UI片段供用户编辑名称。
每个属性页面(代码片段)都应继承自 PropertyPageBase 基类。
即时(图表)编辑器弹窗¶
在图表中双击某一元素时,会弹出编辑窗口,此时可快速修改名称。
默认情况下,此功能适用于所有带名称的元素。如需扩展功能,可注册自定义的行内编辑器函数。