Skip to content

事件总线 ​

双向事件:插件 → 宿主/前端 用 emit_event;宿主 → 插件 用 handle_host_event。禁止轮询宿主私有状态。


1. 插件 → 宿主 / 前端 ​

python
self.emit_event(event_name: str, payload: Any = None) -> None
  • 线程安全,任意线程可调。
  • 桥接为 QML 信号 pluginEvent(plugin_id, event_name, payload: dict)(QML 侧监听它)。
  • payload 非 dict 时自动包成 {"value": payload};None 变 {}。
  • 前端主动调插件用 bridge.invokePluginAction / invokePluginActionAsync → 插件的 action_*。

常用事件名(自定义即可,但下面这些宿主有约定行为):

事件payload宿主行为
device.switching{"device": str, "reason": str}设置页设备行显示「切换中」并禁用下拉;优先展示 reason
device.ready{"device": str}结束「切换中」状态
stream_chunk / stream_done自定(assistant 打字机)由插件的 QML 自行消费

2. 宿主 → 插件(下行) ​

覆盖基类方法:

python
def handle_host_event(self, event_name: str, payload: dict) -> None: ...

订阅方式(二选一,可叠加):

  1. mod.json:
json
"host_events": ["subtitle.updated", "pipeline.state"]
  1. 运行时:
python
host.subscribe_event(event_name: str,
                     callback: Callable[[str, dict], None] | None = None,
                     plugin_id: str | None = None) -> bool
host.unsubscribe_event(event_name: str, plugin_id: str | None = None) -> bool
host.unsubscribe_all_events(plugin_id: str | None = None) -> bool
  • callback 省略时回调插件的 handle_host_event。
  • 未订阅的事件不会推给该插件;host_events: ["*"] 订阅全部。
  • 插件 shutdown 时宿主自动 unsubscribe_all_events。

3. 标准宿主事件 ​

payload 均为 dict,字段只增不删:

事件payload时机
subtitle.updated{"source", "translation", "speaker", "is_partial"}字幕变更(含打字机中间态 is_partial=True)
subtitle.final同上且 is_partial=False定稿句
history.appended{"id", "speaker", "transcript", "translation", "time"}历史新增一条
history.updated{"id", "speaker", "transcript", "translation"}历史既有条目被更新(如补齐译文/延迟)
pipeline.state与 get_pipeline_state() 同构 + "reason"启动/停止/加载/场景切换
provider.changed{"plugin_type", "plugin_id", "track"}引擎/主题切换(track 形如 "inbound")
locale.changed{"locale"}UI 语言切换
config.changed{"plugin_id", "key", "value"}本插件配置被 UI 修改
plugin.enabled / plugin.disabled{"plugin_id"}任意插件启停
hotkey.triggered{"plugin_id", "action", "key"}本插件热键按下(在 handle_action 之前)

作用域限制 ​

config.changed 与 hotkey.triggered 的 payload 含本插件私有数据, 宿主只投递给 plugin_id 对应的插件——其它插件即使订阅了 * 也收不到。 其余事件按订阅广播。


4. 典型用法 ​

python
class MyPlugin(BasePlugin):
    def initialize(self, config=None):
        super().initialize(config)
        self.host.subscribe_event("pipeline.state", self._on_pipeline)   # 运行时订阅
        # 或 mod.json 里写 host_events 后只实现 handle_host_event

    def _on_pipeline(self, event_name: str, payload: dict) -> None:
        self.host.log("info", f"pipeline running={payload.get('running')}")

    def handle_host_event(self, event_name: str, payload: dict) -> None:
        if event_name == "subtitle.final":
            ...

相关 ​

TransBox - 赋能全人类无界限跨语言交流