Mind+ Python 积木模式扩展开发手册¶
本文档将指导开发者创建适用于 Mind+ Python 积木模式的扩展。
1. 扩展包文件结构¶
一个标准的扩展包目录结构如下:
extensionName/ # 扩展库根目录
├── func.js # 生成代码 (原 opcodeFunc.js)
├── index.js # 图形块定义主文件
├── public/ # 静态资源目录 (原 template/)
│ ├── cover.png # 扩展封面图
│ ├── config.json # 扩展配置文件(元数据)
│ ├── libraries/ # Python 扩展库文件目录 (可选)
│ │ └── df_xxx_lib.py # Python 库文件
│ └── requirements.txt # Python 项目依赖包 (可选)
├── icon/ # 图标资源目录
│ ├── blockIcon.svg # 积木图标 (建议使用白色)
│ └── menuIcon.svg # 分类菜单图标 (建议使用积木颜色)
├── locales/ # 国际化语言包
│ ├── zh-cn.json # 简体中文翻译
│ ├── en.json # 英文翻译
│ └── index.js # 翻译入口文件
2. 配置文件 (public/config.json)¶
config.json 是扩展的核心配置文件。
示例配置¶
{
"id": "pinpongBase",
"version": "0.0.1",
"name": {
"zh-cn": "pinpong初始化",
"en": "pinpong initialize"
},
"description": {
"zh-cn": "pinpong库初始化选择主控板功能和gpio",
"en": "initialize pinpong library select board function and GPIO"
},
"author": "DFRobotTest",
"cover": "cover.png",
"main": "main.js",
"isDevice": false,
"mode": "python-block",
"meta": {
"runtimeVersion": "0.0.2"
}
}
关键字段说明¶
| 字段 | 类型 | 说明 |
|---|---|---|
id | string | 扩展唯一标识符。 |
author | string | 与id一起组成扩展唯一标识。 |
version | string | 版本号。 |
name | object | 多语言名称。 |
description | object | 多语言描述。 |
cover | string | 封面图片文件名,需位于 public 目录下。 |
mode | string | 模式,此处应为 python-block。 |
isDevice | boolean | Python模式均为 false。 |
meta.runtimeVersion | string | 扩展 runtime 接口版本(用于控制 API 兼容性)。 |
compatibilityId | string | Mind+V1.x用户库兼容字段。 |
meta.runtimeVersion¶
runtimeVersion 表示开发扩展时依赖的 runtime API 最低版本。应按实际使用的 API 能力填写最小版本,避免随意填写过大导致扩展只能在高版本 Mind+ 中加载。
compatibilityId(仅需兼容V1.x库时使用)¶
如果当前开发的库由Mind+V1.x库转换而来,或者需要在Mind+V2.x中打开Mind+V1.x包含同样用户库的项目文件,则可以使用此字段指定V1.x用户库的id。
注意:如需兼容V1.x版本扩展,需要保证V2扩展库index.js中积木的opcode与V1.x版本扩展库main.ts中对应积木的函数名称一致,并保证积木类型、数量、输入框数量和类型、兼容主板等信息保持一致,并在Mind+V1版本中加载旧扩展的所有积木保存项目,然后在Mind+V2中需要保证可以正常打开。
参考示例: - V1用户库:https://gitee.com/liliang9693/ext-ds1302 - V2用户库:https://gitee.com/mind-plus/ext2-ds1302
格式:"compatibilityId": "[author]-[id]-thirdex"
例如:
- 在V1的扩展库中config.json中,
"id": "oled12864","author": "DFRobot",则在V2的扩展库中的config.json中设置"compatibilityId": "dfrobot-oled12864-thirdex" - 另外也可以直接查看V1导出的.mpext文件名,例如
dfrobot-oled12864-thirdex-V0.0.3.mpext,不带版本号和后缀即为compatibilityId的值;或者也可以在Mind+V2中打开包含这个库的V1的项目文件,会提示“项目中存在尚未兼容的扩展: dfrobot-oled12864-thirdex”,提示语中的字段即为compatibilityId的值。
3. Python 依赖管理 (public/requirements.txt)¶
如果有配置,Mind+会在加载扩展时,在库管理中显示当前扩展的 Python 依赖库。
示例 requirements.txt:
4. 图形块描述文件 (index.js)¶
index.js 是扩展的入口文件。
类结构定义¶
import ArgumentType from '../utils/argument-type';
import BlockType from '../utils/block-type';
import blockIconURI from './icon/blockIcon.svg';
import menuIconURI from './icon/menuIcon.svg';
import Func from './func'; // 引入生成代码类
import { setLocaleData, formatMessage, setLocale } from '../utils/translation';
import LocaleData from "./locales";
setLocaleData(LocaleData);
class Extension {
constructor(runtime, extensionId) {
this.runtime = runtime;
// 初始化生成代码的实例
this.funcs = new Func(runtime, extensionId);
}
// 必须实现:切换语言的钩子
setLocale(locale) {
setLocale(locale);
}
// 必须实现:返回生成代码的实例
getCodePrimitives() {
return this.funcs;
}
// 必须实现:返回扩展的详细信息
getInfo() {
return {
name: "pinpong",
blockIconURI: blockIconURI,
menuIconURI: menuIconURI,
color1: "#FF6680",
color2: "#FF4D6A",
color3: "#FF3355",
blocks: [
{
opcode: 'pinpongInit',
blockType: BlockType.COMMAND,
text: formatMessage({id: 'gui.extension.pinpongBase.pinpongInit', default: 'pinpong初始化'}),
arguments: {}
}
],
menus: {},
};
}
}
export default Extension;
5. 代码生成文件 (func.js)¶
func.js 负责将图形块转换为 Python 代码。
核心结构¶
class Func {
constructor(runtime, extensionId) {
this.runtime = runtime;
}
pinpongInit(generator, block, parameter) {
// 生成 Python 代码逻辑
// 示例:导入库
generator.addImport('import time');
return `print("Hello Python Mode")`;
}
}
export default Func;
6. 翻译资源文件 (locales)¶
locales/zh-cn.json:
{
"gui.extension.pinpongBase.pinpongInit": "pinpong初始化",
"gui.extension.pinpongBase.pinpongUpdateFirmware": "pinpong更新固件 板型[Board]端口[Port]",
"gui.extension.pinpongBase.pinInit": "[Instance]pin初始化 引脚号[Pin] 模式[Mod]",
"gui.extension.pinpongBase.readPinValue": "[Instance]读数字值",
"gui.extension.pinpongBase.setPinValue": "[Instance]设置数字输出 值[Value]",
"gui.extension.pinpongBase.readAnalogValue": "[Instance]读模拟值",
"gui.extension.pinpongBase.setAnalogValue": "[Instance]设置模拟输出(PWM) 值[Value]"
}
7. Python 生成代码 API¶
1. 导入库模块 addImport¶
addImport(code: string)
- 功能:导入 Python 库模块
- 参数:
code- 实际生成代码(code 去掉空格作为 id)- 覆盖规则:相同 id 时覆盖旧代码
- 示例:
- 生成效果:
2. 添加全局变量 addVariable¶
addVariable(id: string, code: string, coverage: boolean = false)
- 功能:定义全局变量
- 参数:
id- 变量字符串标识符code- 实际生成代码coverage- 是否覆盖同 id 变量的生成代码(默认false)- 示例:
- 生成效果:
3. 添加初始化区域代码 addInit¶
addInit(id: string, code: string, priority: number = 0, isCover: boolean = false)
- 功能:添加初始化的代码(相当于 Arduino 的
addSetup) - 参数:
id- 字符串标识符code- 实际生成代码priority- 优先级(0-9,9最靠前,默认 0)isCover- 是否覆盖同 id 的生成代码(默认false)- 示例:
- 生成效果:
4. 添加全局函数 addFunction¶
addFunction(code: string, isCover: boolean = false)
- 功能:添加全局函数
- 参数:
code- 函数内容生成代码(函数名作为 id)isCover- 是否覆盖同 id 的生成代码(默认false)- 示例:
- 生成效果:
5. 创建事件回调函数¶
- 示例:
- 生成效果:
6. 在积木位置生成 code¶
- 位置:
while True:或积木当前位置 - 规则:
- 返回字符串直接插入代码
- 返回数组
[code, priority]处理优先级(如运算符顺序) - 示例:
- 生成效果:
7. 进阶用法¶
- 添加注释
addComment(id: string, comment: any, position: number, isCover: boolean) - 添加错误提示
addErrorPrompt(message: string) - 获取资源路径
get_asset_path_by_name(全局函数) - 示例: