|
1 | 1 | # SecRandom 插件系统 |
2 | 2 |
|
3 | 3 | ## 概述 |
4 | | -SecRandom 支持插件系统,允许用户扩展应用功能。插件可以包含自定义界面和功能。 |
5 | 4 |
|
6 | | -## 插件结构 |
| 5 | +SecRandom 插件系统为应用程序提供了灵活的扩展机制。通过插件系统,开发者可以轻松地添加新功能、扩展现有功能,并与主系统深度集成。 |
7 | 6 |
|
8 | | -每个插件应该包含以下文件: |
| 7 | +## 插件目录结构 |
9 | 8 |
|
10 | 9 | ``` |
11 | | -具体应该根据示例插件的结构进行修改 |
12 | | -app/plugins/your_plugin_name/ |
13 | | -├── plugin.json # 插件配置文件 |
14 | | -├── assets/ # 插件资源文件夹 |
15 | | -│ └── icon.png # 插件图标文件 |
16 | | -│── main.py # 插件主文件 |
17 | | -│── page.py # 插件页面文件(可选) |
| 10 | +app/plugin/ |
| 11 | +├── example_plugin/ # 示例插件 |
| 12 | +│ ├── plugin.json # 插件配置文件 |
| 13 | +│ ├── main.py # 插件主程序 |
| 14 | +│ └── README.md # 插件说明文档 |
| 15 | +└── [其他插件]/ # 其他插件目录 |
| 16 | + ├── plugin.json |
| 17 | + ├── main.py |
| 18 | + └── README.md |
18 | 19 | ``` |
19 | 20 |
|
20 | | -## 插件配置文件 (plugin.json) |
| 21 | +## 插件开发要点 |
| 22 | + |
| 23 | +### 1. 必需文件 |
| 24 | + |
| 25 | +每个插件必须包含以下文件: |
| 26 | + |
| 27 | +- **plugin.json**: 插件配置文件,定义插件的基本信息 |
| 28 | +- **main.py**: 插件主程序,包含插件的核心功能 |
| 29 | +- **README.md**: 插件说明文档,提供使用指南 |
| 30 | + |
| 31 | +### 2. 插件配置文件 (plugin.json) |
21 | 32 |
|
22 | 33 | ```json |
23 | 34 | { |
24 | 35 | "name": "插件名称", |
25 | 36 | "version": "1.0.0", |
26 | | - "author": "作者名称", |
27 | | - "description": "插件描述", |
28 | | - "icon": "plugins/插件名称/assets/icon.png" |
| 37 | + "description": "插件功能描述", |
| 38 | + "author": "插件作者", |
| 39 | + "entry_point": "main.py", |
| 40 | + "min_app_version": "1.0.0", |
| 41 | + "dependencies": [], |
| 42 | + "enabled": true |
29 | 43 | } |
30 | 44 | ``` |
31 | 45 |
|
32 | | -### 配置字段说明 |
33 | | - |
34 | | -- `name`: 插件显示名称 |
35 | | -- `version`: 插件版本号 |
36 | | -- `author`: 插件作者 |
37 | | -- `description`: 插件描述 |
38 | | -- `icon`: 插件图标(使用相对路径-插件文件夹根目录下的assets文件夹,名称要为'icon.png', 'icon.ico', 'icon.svg'其中之一) |
39 | | - |
40 | | -## 插件页面文件 (page.py) |
41 | | - |
42 | | -如果插件需要显示界面,需要创建 `page.py` 文件并包含 `PluginPage` 类: |
| 46 | +### 3. 插件主程序结构 |
43 | 47 |
|
44 | 48 | ```python |
| 49 | +# 导入必要的库 |
| 50 | +import json |
| 51 | +import os |
| 52 | +from typing import Dict, List, Optional |
| 53 | +from qfluentwidgets import * |
45 | 54 | from PyQt5.QtWidgets import * |
46 | 55 | from PyQt5.QtCore import * |
47 | | -from qfluentwidgets import * |
48 | | - |
49 | | - |
50 | | -class PluginPage(QWidget): |
51 | | - def __init__(self, parent=None): |
52 | | - super().__init__(parent) |
53 | | - self.setWindowTitle("插件页面") |
54 | | - self.setup_ui() |
55 | | - |
56 | | - def setup_ui(self): |
57 | | - # 在这里设置你的界面 |
58 | | - layout = QVBoxLayout(self) |
| 56 | +from PyQt5.QtGui import * |
| 57 | +from loguru import logger |
| 58 | + |
| 59 | +# 插件类 |
| 60 | +class MyPlugin: |
| 61 | + def __init__(self): |
| 62 | + self.config_path = "app/plugin/my_plugin/config.json" |
| 63 | + self.config = {} |
| 64 | + self.load_config() |
59 | 65 |
|
60 | | - title_label = TitleLabel("我的插件") |
61 | | - layout.addWidget(title_label) |
| 66 | + def load_config(self): |
| 67 | + """加载配置""" |
| 68 | + try: |
| 69 | + if os.path.exists(self.config_path): |
| 70 | + with open(self.config_path, 'r', encoding='utf-8') as f: |
| 71 | + self.config = json.load(f) |
| 72 | + except Exception as e: |
| 73 | + logger.error(f"加载配置失败: {e}") |
| 74 | + |
| 75 | + def get_info(self) -> Dict: |
| 76 | + """获取插件信息""" |
| 77 | + return { |
| 78 | + "name": "我的插件", |
| 79 | + "version": "1.0.0", |
| 80 | + "description": "插件描述" |
| 81 | + } |
62 | 82 |
|
63 | | - # 添加更多界面元素... |
| 83 | + def execute(self, *args, **kwargs): |
| 84 | + """执行插件功能""" |
| 85 | + return "插件执行成功" |
| 86 | + |
| 87 | +# API 函数 |
| 88 | +def show_dialog(parent=None): |
| 89 | + """显示插件界面""" |
| 90 | + dialog = __MyPluginDialog(parent) # 例子 |
| 91 | + dialog.exec_() |
| 92 | + |
| 93 | +def get_plugin_info() -> Dict: |
| 94 | + """获取插件信息""" |
| 95 | + plugin = MyPlugin() |
| 96 | + return plugin.get_info() |
64 | 97 | ``` |
65 | 98 |
|
66 | | -## 插件管理 |
67 | | - |
68 | | -### 1. 通过设置界面管理 |
| 99 | +## 插件系统特性 |
69 | 100 |
|
70 | | -1. 打开主应用 |
71 | | -2. 点击设置按钮 |
72 | | -3. 选择"插件管理"选项卡 |
73 | | -4. 在插件管理界面中,你可以: |
74 | | - - 查看已安装的插件 |
75 | | - - 导入新的插件包(.zip 文件) |
76 | | - - 删除现有插件 |
77 | | - - 打开插件页面(如果插件有页面文件) |
| 101 | +### 核心优势 |
78 | 102 |
|
79 | | -### 2. 通过托盘菜单快速访问 |
| 103 | +1. **模块化设计**: 每个插件都是独立的模块,便于开发和维护 |
| 104 | +2. **易于集成**: 提供标准的API接口,与主系统无缝集成 |
| 105 | +3. **配置灵活**: 支持动态配置,用户可以自定义插件行为 |
| 106 | +4. **界面统一**: 使用 qfluentwidgets 保持界面风格一致 |
| 107 | +5. **错误处理**: 完善的异常处理和日志记录机制 |
80 | 108 |
|
81 | | -右键点击系统托盘图标,选择"打开插件管理"可以直接进入插件管理界面。 |
| 109 | +### 技术特点 |
82 | 110 |
|
83 | | -### 3. 导入插件 |
| 111 | +- **基于 PyQt5**: 使用成熟的桌面应用框架 |
| 112 | +- **配置管理**: JSON 格式的配置文件,易于编辑和备份 |
| 113 | +- **日志系统**: 集成 loguru 日志库,便于调试和监控 |
| 114 | +- **信号槽机制**: 支持事件驱动的编程模式 |
| 115 | +- **类型提示**: 使用 Python 类型提示,提高代码质量 |
84 | 116 |
|
85 | | -1. 点击"导入"按钮 |
86 | | -2. 选择插件包文件(.zip 格式) |
87 | | -3. 插件包必须包含 `plugin.json` 配置文件 |
88 | | -4. 系统会自动解压并加载插件 |
| 117 | +## 开发指南 |
89 | 118 |
|
90 | | -### 4. 删除插件 |
| 119 | +### 1. 环境要求 |
91 | 120 |
|
92 | | -1. 在插件卡片中点击"删除"按钮 |
93 | | -2. 确认删除操作 |
94 | | -3. 插件将被完全移除 |
| 121 | +- Python 3.8.10+ |
| 122 | +- PyQt5 |
| 123 | +- qfluentwidgets |
| 124 | +- loguru |
95 | 125 |
|
96 | | -## 插件包格式 |
| 126 | +### 2. 开发步骤 |
97 | 127 |
|
98 | | -插件包是一个 .zip 文件,包含以下结构: |
| 128 | +1. **创建插件目录**: 在 `app/plugin/` 下创建插件目录 |
| 129 | +2. **编写配置文件**: 创建 `plugin.json` 定义插件信息 |
| 130 | +3. **实现主程序**: 编写 `main.py` 实现插件功能 |
| 131 | +4. **添加界面**: 创建图形界面(如需要) |
| 132 | +5. **编写文档**: 创建 `README.md` 说明插件用法 |
| 133 | +6. **测试调试**: 测试插件功能并调试问题 |
99 | 134 |
|
100 | | -``` |
101 | | -plugin_name.zip |
102 | | -├── plugin.json |
103 | | -├── page.py (可选) |
104 | | -└── 其他资源文件 (可选) |
105 | | -``` |
| 135 | +### 3. 最佳实践 |
106 | 136 |
|
107 | | -## 示例插件 |
| 137 | +- **命名规范**: 使用清晰的命名约定 |
| 138 | +- **错误处理**: 添加适当的异常处理 |
| 139 | +- **日志记录**: 记录重要的操作和错误 |
| 140 | +- **配置管理**: 合理使用配置文件 |
| 141 | +- **界面设计**: 遵循主系统的界面风格 |
108 | 142 |
|
109 | | -系统提供了一个示例插件 `example_plugin`,你可以参考它的结构来创建自己的插件。 |
| 143 | +### 4. 调试技巧 |
110 | 144 |
|
111 | | -## 注意事项 |
112 | | - |
113 | | -1. 插件目录位于 `app/plugins/` |
114 | | -2. 插件名称必须唯一,不能重复 |
115 | | -3. 插件页面类必须命名为 `PluginPage` |
116 | | -4. 插件可以使用 qfluentwidgets 的所有组件 |
117 | | -5. 插件页面会在独立的窗口中打开 |
118 | | - |
119 | | -## 常用 Fluent Icon |
| 145 | +```python |
| 146 | +# 在 main.py 末尾添加测试代码 |
| 147 | +if __name__ == "__main__": |
| 148 | + app = QApplication([]) |
| 149 | + # 测试插件功能 |
| 150 | + dialog = MyDialog() |
| 151 | + dialog.show() |
| 152 | + app.exec_() |
| 153 | +``` |
120 | 154 |
|
121 | | -- 可以看app\resource\assets路径下的图标 |
122 | | -- 如需增加需要自行添加到assets路径下(需要按照格式添加暗色和亮色图标) |
123 | | -- 或者您可以自己在插件路径下添加图标文件(需要自己在插件中自行写图标的相对路径) |
| 155 | +### 5. 软件没有对应库的情况 |
124 | 156 |
|
125 | | -## 开发建议 |
| 157 | +在插件系统中,如果软件没有对应库的情况,需要在插件的 `plugin.json` 文件中添加 `dependencies` 字段,指定插件依赖的库。例如: |
126 | 158 |
|
127 | | -1. 保持插件简单和专注 |
128 | | -2. 提供清晰的描述和作者信息 |
129 | | -3. 测试插件在不同主题下的显示效果 |
130 | | -4. 遵循现有的 UI 风格和交互模式 |
131 | | -5. 添加适当的错误处理和日志记录 |
| 159 | +```json |
| 160 | +{ |
| 161 | + "name": "插件名称", |
| 162 | + "version": "1.0.0", |
| 163 | + "description": "插件功能描述", |
| 164 | + "author": "插件作者", |
| 165 | + "entry_point": "main.py", |
| 166 | + "min_app_version": "1.0.0", |
| 167 | + "dependencies": ["transformers", "torch"], |
| 168 | + "enabled": true |
| 169 | +} |
| 170 | +``` |
132 | 171 |
|
| 172 | +### 6. SecRandom 程序逻辑是怎么安装python库的? |
133 | 173 |
|
| 174 | +SecRandom 程序在启动时会检查插件目录下的 `plugin.json` 文件,根据 `dependencies` 字段安装插件依赖的库。如果库不存在,程序会自动从 PyPI 下载并安装。 |
134 | 175 |
|
| 176 | +### 7. 插件的依赖库是怎么管理的? |
135 | 177 |
|
136 | | -# 插件依赖离线缓存目录 |
| 178 | +插件的依赖库会被安装到 SecRandom 程序插件目录下的 `site-packages` 目录下。每个插件的依赖库都是独立的,不会与其它插件的库冲突。 |
137 | 179 |
|
138 | | -此目录用于存放插件依赖的离线wheel文件,支持插件在没有网络连接的情况下安装依赖。 |
| 180 | +## 现有插件 |
139 | 181 |
|
140 | | -## 使用方法 |
| 182 | +### 1. 示例插件 (example_plugin) |
| 183 | +- **功能**: 演示插件系统的基本功能 |
| 184 | +- **位置**: `app/plugin/example_plugin/` |
| 185 | +- **用途**: 提供插件开发的示例 |
141 | 186 |
|
142 | | -### 1. 下载wheel文件 |
143 | | -```bash |
144 | | -# 下载指定包的wheel文件 |
145 | | -pip download package_name==version -d resources/wheels/ |
| 187 | +## 常见问题 |
146 | 188 |
|
147 | | -# 下载多个包的wheel文件 |
148 | | -pip download -r requirements.txt -d resources/wheels/ |
149 | | -``` |
| 189 | +### Q: 如何创建一个新的插件? |
| 190 | +A: 复制 `example_plugin` 目录,修改其中的文件来实现你的功能。 |
150 | 191 |
|
151 | | -### 2. 支持的包类型 |
152 | | -- **ollama**: 用于大语言模型交互 |
153 | | -- **transformers**: 用于自然语言处理 |
154 | | -- **torch**: 深度学习框架 |
155 | | -- **numpy**: 数值计算 |
156 | | -- **pandas**: 数据处理 |
157 | | -- **requests**: HTTP请求 |
158 | | -- 其他常用Python包 |
| 192 | +### Q: 插件如何与主系统通信? |
| 193 | +A: 可以通过信号槽、事件系统或直接调用主系统API来实现通信。 |
159 | 194 |
|
160 | | -### 3. 目录结构 |
161 | | -``` |
162 | | -resources/wheels/ |
163 | | -├── ollama-0.1.0-py3-none-any.whl |
164 | | -├── transformers-4.20.0-py3-none-any.whl |
165 | | -├── torch-1.12.0-cp39-cp39-win_amd64.whl |
166 | | -├── numpy-1.21.0-cp39-cp39-win_amd64.whl |
167 | | -└── ... |
168 | | -``` |
| 195 | +### Q: 如何处理插件的配置? |
| 196 | +A: 使用 JSON 格式的配置文件,在插件初始化时加载,修改时保存。 |
169 | 197 |
|
170 | | -### 4. 插件依赖安装流程 |
171 | | -1. 插件加载时检查 `__requirements__.txt` 文件 |
172 | | -2. 在插件目录下创建 `site-packages` 目录 |
173 | | -3. 使用以下命令安装依赖: |
174 | | - ```bash |
175 | | - pip install --target <plugin_dir>/site-packages -r __requirements__.txt --find-links resources/wheels |
176 | | - ``` |
177 | | -4. 将 `site-packages` 目录添加到 `sys.path` |
178 | | -5. 依赖安装成功后加载插件 |
179 | | - |
180 | | -### 5. 注意事项 |
181 | | -- wheel文件应该与目标Python版本兼容 |
182 | | -- 建议定期更新wheel文件以获取最新版本 |
183 | | -- 某些包可能需要额外的系统依赖 |
184 | | -- 在Windows环境下,优先下载 `.whl` 文件而非源码包 |
185 | | - |
186 | | -## 维护建议 |
187 | | - |
188 | | -### 定期更新wheel文件 |
189 | | -```bash |
190 | | -# 批量更新常用包 |
191 | | -pip download --upgrade ollama transformers torch numpy pandas requests -d resources/wheels/ |
192 | | -``` |
| 198 | +### Q: 插件的界面如何保持一致? |
| 199 | +A: 使用 qfluentwidgets 库创建界面,遵循主系统的设计规范。 |
193 | 200 |
|
194 | | -### 清理旧版本 |
195 | | -```bash |
196 | | -# 删除指定包的旧版本 |
197 | | -find resources/wheels/ -name "package_name-*" -not -name "package_name-latest-version*" -delete |
198 | | -``` |
| 201 | +--- |
199 | 202 |
|
200 | | -### 验证wheel文件完整性 |
201 | | -```bash |
202 | | -# 检查wheel文件是否损坏 |
203 | | -for file in resources/wheels/*.whl; do |
204 | | - if unzip -t "$file" > /dev/null 2>&1; then |
205 | | - echo "✓ $file is valid" |
206 | | - else |
207 | | - echo "✗ $file is corrupted" |
208 | | - fi |
209 | | -done |
210 | | -``` |
| 203 | +© 2025 SecRandom. All rights reserved. |
0 commit comments