tool — 工具 / 文本源 / 划词
不挂 ASR→MT→TTS 管线,靠全局热键 +
action_*提供能力:划词翻译、取词、贴字、 外部数据源等。可多开。⚠️ 工具类必须用正式的
type: "tool",不要借middleware挂action_*—— 那会让 工坊分类与热键语义都错。
声明
json
{
"id": "example.select_translate",
"version": "1.0.0",
"target_app_version": "0.2",
"type": "tool",
"entrypoint": "select_translate.py:SelectTranslatePlugin",
"hotkeys": [
{ "action": "translate_selection", "default": "Alt+T", "name": "划词翻译" }
],
"config_schema": [
{ "key": "capture_mode", "label": "捕获方式", "type": "select",
"choices": ["auto", "clipboard"], "default": "auto" },
{ "key": "speak_translation", "label": "划词后朗读译文", "type": "boolean", "default": false }
]
}hotkeys[].action 对应实现里的 action_<action> 方法。
type=tool的已启用插件在扫描阶段就会预加载实例(因为要注册热键), 所以initialize()会在启动时跑,别在里面做重活。
最小骨架
python
from transbox.plugins.base import BasePlugin
class HelloTool(BasePlugin):
def initialize(self, config=None) -> None:
super().initialize(config)
self.host.register_plugin_hotkey(self.id, "run", "Alt+T", name="我的工具")
def action_run(self, **kwargs) -> dict:
ok = self.host.feed_direct_caption("hello", "auto", tts=False, drop_noise=False)
return {"ok": ok}
def handle_host_event(self, event_name: str, payload: dict) -> None:
if event_name == "pipeline.state":
self.host.log("info", f"pipeline: {payload.get('running')}")
def shutdown(self) -> None:
self.host.unregister_plugin_hotkeys(self.id)
super().shutdown()hotkeys声明式注册(宿主在 Qt 主线程RegisterHotKey),也可以运行时host.register_plugin_hotkey(...),见 全局热键。- 动作分发:
handle_action(action, params)→action_<action>(**params); QML 侧用bridge.invokePluginAction/invokePluginActionAsync调。 - 返回 dict 会原样回给调用方。
把文本送进字幕
两条路(见 字幕与翻译):
| 用法 | 何时用 |
|---|---|
host.feed_direct_caption(text, lang, tts=…, drop_noise=…) | 只有原文,要宿主帮你走完整链路(同传在跑 = 完整链路;没跑 = 轻量 MT+字幕+历史) |
host.feed_caption(text, translation, lang, source=…) | 你已经拿到译文(划词翻译、字幕桥补帧),不想再过一遍 MT |
工具类的 drop_noise 必须传 False(不要吞掉短词)。
典型场景
| 场景 | 关键点 |
|---|---|
| 划词翻译 | 读剪贴板/选区 → host.translate() 或 feed_direct_caption → 可选 host.speak() |
| 外部数据源 | 后台线程轮询/订阅 → feed_direct_caption |
| 贴字 HUD | host.create_plugin_window(...) 开一个穿透+防录屏浮窗(插件浮窗) |
| 批量处理 | host.begin_progress() + is_progress_cancelled()(文件选择与长任务) |
参考实现
extensions/community_select_translate/(划词翻译,type=tool 的标准范例)。
