PyForge Studio 插件开发文档

版本 v2.0 · 适用于 PyForge Studio ≥ 2.13

欢迎来到 PyForge Studio 的插件开发世界!本文档将指导你从零开始,为 PyForge 编写功能强大的插件。 无论你是想增加一个快捷键、添加一个代码格式化工具,还是集成网络服务,PyForge 的插件系统都能让你轻松扩展 IDE 的功能。

1. 概述

PyForge Studio 的插件系统基于 微内核架构 设计:

当前插件系统版本:v2.0 · 支持 UUID 精确定位、依赖管理(前置插件 + pip 包)、API 版本兼容性检查。

2. 插件文件结构

一个标准的插件压缩包(.zip)内部应包含以下文件:

YourPlugin.zip
├── Include.json      # 必须,元数据文件
└── init.py           # 必须,插件入口脚本

插件安装后,主程序会将其解压到 .plugin/extracted/ 目录,并以 UUID 作为唯一标识。

3. Include.json 详细说明

Include.json 是一个 JSON 格式的元数据文件,用于声明插件的身份、依赖和 API 信息。 所有字段均区分大小写。

3.1 基础字段

{
  "plugin_uuid": "com.yourstudio.yourplugin",   // 必填,全局唯一标识符
  "name": "Your Plugin Name",                  // 必填,显示名称
  "version": "1.0.0",                          // 必填,语义化版本号
  "provides_api": false,                       // 可选,是否提供 API
  "dependencies": {                            // 可选,依赖声明
    "pip": [],                                 // pip 依赖列表
    "plugins": []                              // 前置插件依赖列表
  }
}

3.2 字段详解

字段类型说明
plugin_uuid 字符串 必填。全局唯一标识符,建议使用反向域名格式(如 com.yourstudio.plugin)。
name 字符串 必填。插件在 UI 中显示的名称。
version 字符串 必填。语义化版本号(如 1.2.3)。
provides_api false{"version":"..."} 可选,默认 false。若提供 API,需指定版本号,如 {"version":"1.0"}。 其他插件可通过依赖此插件并指定所需 API 版本来调用。
dependencies 对象 可选,默认为 {"pip": [], "plugins": []}
· pip:Python 包列表(如 ["requests"]),加载时自动安装。
· plugins:前置插件列表,每个对象包含 uuidapi_version

4. init.py – 插件入口脚本

init.py 是插件的核心执行文件,主程序会在满足所有依赖后动态加载它。 必须包含一个 register(editor) 函数,作为插件的入口点。

import tkinter as tk
from tkinter import messagebox

def register(editor):
    """
    插件注册函数
    :param editor: PythonEditor 实例,提供核心 API
    """
    # 在这里编写你的插件逻辑
    pass

5. editor API 参考

register 函数中,你获得的 editor 对象提供了以下常用属性和方法:

API类型说明
editor.roottk.Tk主窗口对象
editor.code_editorScrolledText代码编辑器控件
editor.current_filestr / None当前打开的文件路径
editor.log_info(msg)方法打印信息日志(控制台)
editor.log_error(msg)方法打印错误日志
editor.add_plugin_menu_item(label, cmd)方法在“插件”菜单添加菜单项
editor.run_in_thread(func, *args)方法在后台线程运行函数,避免阻塞 UI
editor.save_file()方法保存当前文件
editor.run_code()方法运行当前文件
editor.get_plugin_dir()方法获取插件根目录路径
editor.utils对象工具库(需依赖 com.rauto.utils
提示: editor.utils 仅在依赖插件 com.rauto.utils 已加载时可用。 如需使用,请在 Include.jsondependencies.plugins 中声明。

6. editor.utils 工具库

需要依赖 com.rauto.utils 插件(UUID: com.rauto.utils)。

方法说明
utils.read_text(path)读取文本文件,返回字符串
utils.write_text(path, content)写入文本文件
utils.read_json(path)读取并解析 JSON 文件
utils.write_json(path, data)将数据写入 JSON 文件
utils.http_get(url, params, headers, timeout)发起 GET 请求(需 requests
utils.http_post(url, data, json, headers, timeout)发起 POST 请求
utils.show_info(title, message)显示信息提示框
utils.show_error(title, message)显示错误提示框
utils.show_yesno(title, message)显示“是/否”对话框,返回 True/False
utils.get_string(title, prompt, initialvalue)显示输入框,返回用户输入
utils.show_progress(title, maximum)显示进度条窗口,返回 (update, close)
utils.run_in_thread(func, *args, callback)后台运行函数,完成后通过回调更新 UI
utils.run_in_main_thread(func, *args)在主线程执行函数(用于更新 UI)
utils.subscribe(event, callback)订阅事件(跨插件通信)
utils.publish(event, *args, **kwargs)发布事件,触发所有订阅者
utils.get_timestamp()返回当前时间字符串
utils.get_plugin_dir()返回当前插件的目录

示例:添加一个菜单项

def register(editor):
    def say_hello():
        editor.utils.show_info("问候", "你好,世界!")

    editor.add_plugin_menu_item("👋 问候", say_hello)
    editor.log_info("问候插件加载成功")

示例:访问编辑器内容

def register(editor):
    def count_lines():
        content = editor.code_editor.get("1.0", tk.END)
        lines = content.count('\n')
        messagebox.showinfo("行数统计", f"当前文件共有 {lines} 行")

    editor.add_plugin_menu_item("📊 统计行数", count_lines)

7. 依赖管理与版本兼容性

7.1 声明依赖

Include.json 中可声明两种依赖:

  1. Python 包(pip):在 dependencies.pip 数组中列出包名,加载器自动检查并安装。
  2. 前置插件:在 dependencies.plugins 中指定 uuidapi_version

7.2 版本比较规则

主程序使用 语义化版本 比较(>=)。要求 "1.2",前置插件提供 "1.3" 则兼容;若提供 "1.1" 则不兼容并提示错误。

7.3 加载流程

  1. 扫描 .plugin 目录下所有 .zip 文件。
  2. 解压每个插件,读取 Include.json,注册 UUID 和元数据。
  3. 对每个插件检查 dependencies.plugins
    • 若前置插件 UUID 不存在 → 弹出“缺少前置插件”
    • 若前置插件未声明 provides_api → 不兼容
    • 若 API 版本不满足要求 → 弹出“API 版本不兼容”
  4. 依赖检查通过后,执行 init.py 中的 register
若某个插件因依赖问题未能加载,它会在“插件管理”窗口中显示“错误”状态。

8. 插件管理窗口

用户可以通过菜单 “插件” → “管理插件” 打开插件管理窗口,查看所有已注册插件的 UUID、名称、版本、是否提供 API 以及状态(已加载/错误)。用户还可以在此窗口卸载插件。

9. 开发与调试建议

9.1 日志输出

使用 editor.log_info()editor.log_error() 输出日志,这些信息会显示在控制台(如果从命令行启动)或日志文件中。

9.2 热重载

修改插件代码后,无需重启 IDE,只需点击 “插件” → “刷新插件” 即可重新加载所有插件(注意:已注册的菜单项可能需要手动刷新)。

9.3 测试依赖

建议先安装 RautoStudio_Universal_utils(UUID: com.rauto.utils)作为基础工具库。

9.4 常见错误及解决

错误现象可能原因解决方法
插件未被加载Include.json 缺少 plugin_uuid添加 UUID
状态显示“错误”init.py 缺少 register 或语法错误检查并修正
提示“缺少前置插件”依赖的插件未安装安装对应的 .zip 插件
提示“API版本不兼容”前置插件提供的 API 版本低于要求更新前置插件或降低版本要求
菜单项未出现未调用 editor.add_plugin_menu_itemregister 中添加调用

10. 完整插件示例(带依赖)

以下是一个完整的插件示例,它依赖 com.rauto.utils 工具库,并添加一个“显示当前时间”的菜单项。

Include.json

{
  "plugin_uuid": "com.rauto.clock",
  "name": "时钟插件",
  "version": "1.0.0",
  "provides_api": false,
  "dependencies": {
    "pip": [],
    "plugins": [
      { "uuid": "com.rauto.utils", "api_version": "1.0" }
    ]
  }
}

init.py

import datetime

def register(editor):
    def show_time():
        now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        editor.utils.show_info("当前时间", now)

    editor.add_plugin_menu_item("🕒 显示时间", show_time)
    editor.log_info("时钟插件已加载")

打包为 clock.zip 后,用户即可通过“安装插件”功能安装。

11. 发布与分发

12. 获取帮助

祝你在 PyForge 的插件开发之旅愉快!
—— Rauto Studio 团队