Wox Python 插件 SDK 完整开发指南:从 Plugin 基类到动态设置与查询精化
2026/9/20 14:27:35 网站建设 项目流程

Wox Python 插件 SDK 完整开发指南:从 Plugin 基类到动态设置与查询精化

【免费下载链接】WoxA cross-platform launcher that simply works项目地址: https://gitcode.com/gh_mirrors/wo/Wox

本篇指南以 Wox 官方 Python 插件 SDK 参考文档(.agents/skills/wox-plugin-creator/references/sdk_python.md)为核心骨架,结合仓库中wox.plugin.python/src/wox_plugin/的源码实现,系统讲解如何在 Wox 中开发 Python 插件:从环境准备、安装wox-plugin包、实现Plugin基类与数据模型,到熟练使用全部 Public API、编写可云同步的设置、配置 QueryRequirements、实现动态设置与静态 HTML 预览。读完本文,你将能独立完成一个结构规范、功能完整的 Wox Python 插件,并理解每个 API 背后的调用语义与版本约束。

Wox 要求Python 3.10 或更高版本。这一约束在仓库源码中有双重印证:wox.plugin.python/pyproject.toml中声明requires-python = ">=3.10",而 Python 宿主实现 中同样定义了minimumPythonVersion = v3.10.0,并在解析到低于该版本的解释器时直接报错,保证 API 解析器与宿主进程使用同一套版本规则。

环境准备与 SDK 安装

安装 wox-plugin 包

在插件项目目录中执行:

uv add wox-plugin

该命令通过uvwox-plugin加入项目依赖。包内部组织清晰:顶层__init__.py统一导出PluginQueryQueryResponseResultContextPluginInitParams以及WoxImageWoxPreviewLogLevel、设置辅助函数等全部公开符号(见 SDK 包导出),因此from wox_plugin import ...一条导入即可覆盖绝大多数场景。

插件元数据 plugin.json

插件根目录需要plugin.json声明元数据,其中Runtime必须为"python"Entry指向插件入口脚本(如main.py)。若插件返回QueryResponse,则MinWoxVersion必须声明为>= 2.0.4(参见 SDK 元数据示例)。

Plugin 基类与最小可运行插件

所有 Wox Python 插件的入口都实现Plugin协议(协议定义),至少包含两个异步方法:

from wox_plugin import Plugin, Query, QueryResponse, Result, Context, PluginInitParams class MyPlugin(Plugin): async def init(self, ctx: Context, params: PluginInitParams) -> None: self.api = params.api async def query(self, ctx: Context, query: Query) -> QueryResponse: return QueryResponse(results=[])
  • init(ctx, params):插件加载时调用一次,应尽快返回。params.apiPublicAPI实例(类型见 PublicAPI 协议),params.plugin_directory是插件目录绝对路径,可用于加载配置文件与资源。
  • query(ctx, query):用户输入命中插件时调用。返回QueryResponse(要求MinWoxVersion >= 2.0.4)或直接返回List[Result](兼容旧版本 Wox 的弃用路径)。

文件末尾实例化单例:

plugin = MyPlugin()

返回值的版本语义

从源码注释(Plugin 协议兼容性说明)可以确认:直接返回List[Result]仍被宿主接受,但属于弃用路径;只有QueryResponse能把结果、refinements 与 layout 提示放在同一个载荷中一并上送。因此新插件应统一使用QueryResponse

查询作用域布局(query-scoped layout)

QueryResponse.layout是查询级的布局声明,包含result_preview_width_ratiogrid_layout两个可选字段(QueryLayout 实现):

from wox_plugin import QueryResponse, QueryLayout, QueryGridLayout return QueryResponse( results=results, layout=QueryLayout( result_preview_width_ratio=0.6, grid_layout=QueryGridLayout(columns=3, image_width=200, image_height=200, show_title=True), ), )

QueryGridLayout还支持item_paddingitem_marginaspect_ratiocommands等字段(QueryGridLayout 实现)。旧版的resultPreviewWidthRatiogridLayout元数据特性已被弃用,原因正如源码注释所指:它们只能描述静态的插件或命令默认值,无法像QueryResponse.layout一样按每次查询动态决策。

核心数据模型

Query

class Query: type: str # "input" 或 "selection" raw_query: str trigger_keyword: str command: str search: str refinements: dict[str, str] # 已选中的 refinement 值
  • type对应QueryType.INPUT(在搜索框输入)或QueryType.SELECTION(在外部应用选中文本/文件后唤起 Wox),见 QueryType 定义。
  • trigger_keyword是插件触发词,command是已注册的子命令关键字,search是去除触发词与命令后的实际搜索文本。
  • refinements保存用户在查询作用域精化控件上的选择。

QueryRefinement

class QueryRefinement: id: str title: str type: QueryRefinementType # singleSelect | multiSelect | toggle | sort hotkey: str # macOS 上为 cmd+t,Windows/Linux 上为 ctrl+t options: list[QueryRefinementOption] default_value: list[str] = [] persist: bool = False
  • typeQueryRefinementType枚举(SINGLE_SELECT/MULTI_SELECT/TOGGLE/SORT),见 query_response.py。
  • hotkey必须是真实的平台组合键:macOS 用cmd+<key>,Windows/Linux 用ctrl+<key>。代码中应检测sys.platform == "darwin"后输出对应字符串,切勿直接写死字面量ctrl/cmd+t
  • 插件通过QueryResponse.refinements返回精化控件,并在下一次查询时从query.refinements读取已选值(详见references/refinements.md)。

Result

class Result: title: str # 支持 "i18n:key" 前缀自动翻译 icon: WoxImage sub_title: str = "" # 支持 "i18n:key" 前缀 actions: List[ResultAction] = [] score: float = 0.0 context_data: Any = None

源码中的 Result 模型 还提供了更多字段:id(跨更新追踪结果)、preview(详情面板预览)、group/group_score(结果分组与组排序)、tails(文本/图片尾巴元素)、drag_data(原生文件拖拽)等。score决定排序,数值越高越靠前。

ResultAction支持EXECUTE(立即执行)与FORM(先展示表单再提交,回调收到FormActionContext.values)两种类型,并可用prevent_hide_after_action=True保持 Wox 窗口在执行动作后不隐藏,详见 ResultAction 模型。

WoxImage

class WoxImage: @classmethod def new_emoji(cls, char: str) -> "WoxImage" @classmethod def new_absolute(cls, path: str) -> "WoxImage" @classmethod def new_relative(cls, path: str) -> "WoxImage"

WoxImage 实现 支持多种图片类型:ABSOLUTERELATIVE(相对插件目录)、BASE64(完整 data URI)、SVG(内联 SVG 标记)、EMOJIURLTHEME(内置主题图标,随明暗主题自适应)、FILE_ICON(按文件扩展名取系统图标)。对应工厂方法还包括new_base64()new_svg()new_url()new_theme()等。

Action 图标应使用可适配主题的 SVGsvg:或使用var(--wox-theme-icon-color)的内联标记),而不是 emoji,详见references/icons.md

Public API 方法全览

所有方法均为异步且需要ctx。以下是 SDK 参考文档列出的核心 API,按类别整理:

通用控制

方法作用
change_query(ctx, query: PlainQuery)更新搜索栏内容(支持ChangeQueryParam指定查询类型与文本/选区)
hide_app(ctx)隐藏 Wox
show_app(ctx)显示 Wox
notify(ctx, message)显示系统通知(支持 i18n key)
log(ctx, level, msg)写日志,levelLogLevel枚举(INFO/ERROR/DEBUG/WARNING
copy(ctx, params: CopyParams)复制文本或图片到剪贴板
is_visible(ctx)检查 Wox 窗口是否可见

缓存

插件需要磁盘缓存时,优先使用get_cache_folder,不要自创目录

  • get_cache_folder(ctx):返回~/.wox/cache/plugins/<plugin-id>/。Wox 会在需要时自动创建,并在插件卸载时删除。
  • init()中调用一次并保存路径,把下载文件、缩略图、搜索结果等写入其下。
  • 不要在插件文件旁、用户数据目录下或硬编码文件夹名下自行发明cache/tmp/downloads/目录。
  • 用户偏好与收藏属于设置而非缓存,请使用get_setting/set_setting

该 API 在 PublicAPI 协议 中有完整的路径语义注释。

设置

插件设置应优先使用以下 API——这些值可以通过 Wox 云同步跨设备同步,不要把普通设置持久化到本地文件或自定义存储中:

  • get_setting(ctx, key):读取设置值(未设置时返回默认值)。
  • save_setting(ctx, key, value, is_platform_specific):保存设置。普通插件设置可参与云同步;对于本地路径、可执行文件路径、shell 命令、热键、浏览器配置、应用路径、系统集成等仅限当前平台的值,is_platform_specificTrue
  • on_setting_changed(ctx, callback):注册设置变更回调,回调签名(ctx, key, new_value)
  • on_get_dynamic_setting(ctx, callback):为dynamic类型设置提供运行时生成的设置定义,回调返回PluginSettingDefinitionItem

save_setting在源码中已被标注为 Deprecated(api.py 中的说明),新插件在MinWoxVersion >= 2.4.0时应改用set_setting(ctx, SetSettingOption(...)),后者通过platform_specificis_local两个布尔字段显式控制跨平台与设备本地行为(见 SetSettingOption 实现)。

UI 实时更新

  • update_result(ctx, result: UpdatableResult):实时更新结果(用于动作处理中的长任务进度展示)。
  • push_results(ctx, query, results):向当前查询追加结果(适合流式返回、分批加载)。
  • refresh_query(ctx, param):以现有文本重新执行查询(RefreshQueryParam.preserve_selected_index控制是否保持选中项)。
  • get_updatable_result(ctx, result_id):获取某结果的当前 UI 状态,结果已不可见时返回None

AI 与国际化

  • ai_chat_stream(ctx, model, convs, options, callback):流式获取 LLM 响应。modelAIModel(name=..., provider=...)convsConversation列表(可用user_message()/assistant_message()便捷构造),回调接收ChatStreamData(状态为STREAMING/FINISHED/ERROR)。
  • get_translation(ctx, key):获取原始翻译字符串。注意返回的是原始字符串,参数替换需自行用 f-string 或.format()完成。

设置编写要点

  • 插件设置一律走get_setting/save_setting/on_setting_changed,以便参与 Wox 云同步;不要让用户期望"换设备还在"的值落入本地文件。
  • 缓存文件放在get_cache_folder(ctx)下,不要在插件目录或用户数据树下自造缓存目录。
  • Python SDK 内置以下设置构建辅助函数(定义见 setting.py):
    • create_textbox_setting(key, label, default_value="", tooltip=""):单行文本框设置。
    • create_checkbox_setting(key, label, default_value="false", tooltip=""):布尔开关("true"为选中)。
    • create_label_setting(content, tooltip=""):只读说明文字。
  • 目前没有内置create_select_setting()辅助函数。
  • 对于selecttable、校验器、dynamic等高级设置,需要直接构造PluginSettingDefinitionItem与对应的值对象(如PluginSettingValueTablePluginSettingValueTableColumnPluginSettingValueTableGroup),或手动输出期望的 JSON 结构。设置类型枚举见 PluginSettingDefinitionType(head/textbox/checkbox/select/label/newline/table/dynamic)。
  • 精确的plugin.json与校验器结构请阅读references/plugin_json_schema.md;可直接复制的高级设置示例见references/settings_patterns.md
  • 运行时save_setting(ctx, key, value, is_platform_specific)调用必须与设置元数据保持一致:如果对应SettingDefinitions条目声明了IsPlatformSpecific: true,不要对动态保存的设置硬编码False
  • DisabledInPlatforms只控制设置在哪些平台被禁用,不会隔离云同步的值
  • 当查询依赖 API Key 等设置时,在plugin.json中使用静态QueryRequirements。Wox 会在调用query()之前拦截查询,仅显示内置的query_requirement_settings配置预览。
  • 不存在运行时的register_query_requirementsAPI,查询需求一律在元数据中声明。

QueryRequirements 数据类与元数据示例

from dataclasses import dataclass, field @dataclass class PluginQueryRequirement: setting_key: str validators: list[dict] = field(default_factory=list) message: str = "" @dataclass class PluginQueryRequirements: any_query: list[PluginQueryRequirement] = field(default_factory=list) query_without_command: list[PluginQueryRequirement] = field(default_factory=list) query_with_command: dict[str, list[PluginQueryRequirement]] = field(default_factory=dict)

其语义在 PluginQueryRequirements 源码 中有明确注释:any_query作用于所有查询,query_without_command仅作用于无子命令的查询,query_with_command按命令关键字分别配置。to_dict()会转换成plugin.json使用的 PascalCase 字段名。

元数据示例:

{ "SettingDefinitions": [ { "Type": "textbox", "Value": { "Key": "accessKey", "Label": "i18n:access_key", "DefaultValue": "", "Validators": [{ "Type": "not_empty", "Value": {} }] } } ], "QueryRequirements": { "AnyQuery": [ { "SettingKey": "accessKey", "Message": "i18n:access_key_required" } ], "QueryWithoutCommand": [], "QueryWithCommand": {} } }

校验器类型除not_empty外,仓库setting/validator/目录还提供is_numberis_urlunique等实现可供参考。

动态设置(Dynamic Setting)示例

动态设置由on_get_dynamic_setting回调在运行时生成定义,适合值取决于当前状态(如预览、可选列表)的场景:

from wox_plugin import ( PluginSettingDefinitionItem, PluginSettingDefinitionType, PluginSettingValueLabel, ) async def _on_get_dynamic_setting(ctx, key): if key == "separator_preview": return PluginSettingDefinitionItem( type=PluginSettingDefinitionType.LABEL, value=PluginSettingValueLabel(content="Preview: 1,234.56"), ) return PluginSettingDefinitionItem( type=PluginSettingDefinitionType.LABEL, value=PluginSettingValueLabel(content="Unknown setting"), )

回调在init()中注册:await self.api.on_get_dynamic_setting(ctx, self._on_get_dynamic_setting)

完整使用示例:带 i18n 格式化的 Hello 插件

from wox_plugin import Plugin, Query, Result, WoxImage class HelloPlugin(Plugin): async def init(self, ctx, params): self.api = params.api async def query(self, ctx, query): # I18n with formatting raw_fmt = await self.api.get_translation(ctx, "hello_format") # "Hello {name}" title = raw_fmt.format(name=query.search) return [Result( title=title, icon=WoxImage.new_emoji("👋"), actions=[] )] plugin = HelloPlugin()

注意:get_translation返回的是包含{name}占位符的原始字符串,需用.format()完成替换——这正是 SDK 参考中强调的要点。

静态 HTML 预览(WEBVIEW)

预览结果时,使用WoxPreviewType.WEBVIEW并传入 JSON 编码的html字段即可,无需 HTTP 服务器或临时 HTML 文件,也不存在独立的html预览类型

import json from wox_plugin import WoxPreview, WoxPreviewType preview = WoxPreview( preview_type=WoxPreviewType.WEBVIEW, preview_data=json.dumps({ "html": '<!doctype html><html><body><h1 style="color:teal">Hello Wox</h1></body></html>' }), ) # Assign preview to Result(preview=preview, ...).
  • htmlurl二选一。可选 JSON 字段:injectCssuserAgentcacheDisabledcacheKey(默认取 URL 或 HTML 内容)。
  • 内联 HTML 没有相对插件的 base URL:请内联 CSS/图片或使用绝对资源 URL。
  • 这是浏览器内容而非经过净化的 Markdown;拼接不可信文本前务必使用html.escape

WoxPreview模型还支持MARKDOWNTEXTIMAGEURLFILELISTREMOTE等类型(WoxPreviewType 定义),其中LIST可通过WoxPreviewListData展示带图标、副标题与尾巴的结构化行。

结构化查询参数与命令块

  • 命令的别名配置在Commands[].Aliases,后缀模板配置在Commands[].QueryHint,完整的ChangeQuery实例与 SDK 用法详见.agents/skills/wox-plugin-creator/SKILL.mdQueryHint章节。
  • QueryHintinput查询仍是可选项;不要在QueryText中嵌入标记,也不要从粘贴文本中推断参数边界。

常用参考路径

  • SDK 参考文档(本文依据)
  • Python SDK 包导出
  • PublicAPI 协议与全部方法签名
  • Plugin 协议与生命周期
  • Result / ResultAction / UpdatableResult 模型
  • QueryResponse / Refinement / Layout 模型
  • 设置定义模型与辅助函数
  • WoxImage 图片模型
  • WoxPreview 预览模型
  • Python 宿主版本校验
  • 配套参考:插件 JSON Schema、设置模式、精化控件、图标规范、i18n

【免费下载链接】WoxA cross-platform launcher that simply works项目地址: https://gitcode.com/gh_mirrors/wo/Wox

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询