QML 界面插槽与 HostContext
在 mod.json 的 ui_extensions 里把插槽名映射到包内 .qml 文件,即可替换对应视觉区域,无需改主程序。

1. 已消费插槽(可安全使用)
| 插槽 | 替换区域 | 用途 |
|---|---|---|
overlay_background | 字幕悬浮窗底板 | 毛玻璃、渐变、噪点 |
caption_view | 字幕排版区 | 自定义双语布局 |
audio_level | 右下角音量/律动条 | 波形、频谱 |
alert_capsule | 缺 Key / 模型未就绪提示胶囊 | 自定义告警 UI |
overlay_decorations | 悬浮窗顶层装饰 | HUD 切角、粒子 |
style_bar_actions | 控制条动作扩展区 | 额外按钮 |
settings_background | 设置中心底板 | 与主题统一 |
history_background | 历史窗口底板 | — |
dialog_background | 对话框/模态底板 | — |
window_background | 多窗口级联回退层 | 设置/历史等 fallback |
当前未消费(注册了但没有 Loader,不要依赖):overlay_root、style_bar。
非标准键 settings_view:
不走上述插槽链,由设置页插件容器读取,用于引擎/套件的完整配置界面。
2. 级联回退
多窗口背景会按顺序尝试:
- 对话框类:
dialog_background→window_background→overlay_background - 设置/历史:
window_background→overlay_background
因此只写 overlay_background 时,其它窗口仍可能复用你的底板风格。
3. window_backdrop
写在 theme.json(不是 mod.json):
| 值 | 含义 |
|---|---|
acrylic | Windows 亚克力 |
mica / mica_alt | 云母(Win11) |
blur | 模糊 |
none | 不用系统材质 |
QML 内也可调用 hostContext.window.setBackdrop("acrylic")。
4. HostContext(悬浮窗类插槽)
宿主向组件根对象注入 property var hostContext:
import QtQuick 2.15
Item {
id: root
property var hostContext: null
readonly property color textColor:
hostContext ? hostContext.style.textColor : "#ffffff"
readonly property string translation:
hostContext ? hostContext.subtitle.currTranslation : ""
readonly property bool hovered:
hostContext ? hostContext.window.hovered : false
function callPython() {
if (!hostContext) return
hostContext.invoke("my.plugin.id", "ping", { "n": 1 })
}
Rectangle {
anchors.fill: parent
color: hostContext ? hostContext.style.bgColor : "#00000000"
opacity: hostContext ? hostContext.style.bgOpacity : 1.0
Text {
anchors.centerIn: parent
text: translation
color: textColor
font.pixelSize: hostContext ? hostContext.style.fontSize : 24
font.family: hostContext ? hostContext.style.fontFamily : "sans-serif"
}
}
}子系统
styletextColor · bgColor · fontOpacity · bgOpacity · fontSize · fontFamily · themeId · primary · primaryHover · primaryGlow · radiusLarge
subtitlecurrSource · currTranslation · hasRealSubtitle · prevSource · prevTranslation · hasPrev · isTyping · isSourceActive · isTranslationActive
audioisMicMuted · audioDuckingEnabled · playbackDevice
windowhovered · dragging · width · height · setBackdrop(type) · setClickThrough(bool)
RPChostContext.invoke(pluginId, action, params) → Python handle_action → action_<action>(**params)
5. 额外注入属性(按插槽)
| 插槽 | 额外属性 / 信号 |
|---|---|
overlay_background 等 | hovered, appState |
caption_view | appState, bridge |
alert_capsule | alertType, alertCategory, showCapsule;信号 closeRequested, gotoSettingsRequested, switchLocalRequested |
style_bar_actions | hostContext |
| 窗口底板类 | window, appState, 可用 customRadius |
多窗口底板可声明:
property bool enforceCustomRadius: true
property real customRadius: 16
property real customOpacity: 0.856. settings_view(插件设置页)
mod.json:
{
"ui_extensions": {
"settings_view": "CustomSettingsView.qml"
},
"has_settings_tab": true,
"tab_id": "my_plugin",
"tab_title": "我的插件"
}组件根对象可声明(宿主按需赋值):
property string pluginId: ""
property var bridge: null
property var rootWin: null
property var pluginConfig: ({})保存示例:
if (bridge) {
bridge.setPluginConfigValue(pluginId, "gain_db", 12.5)
}仅需表单时:不必写 settings_view,用 config_schema 即可。
7. 实战:替换音量条
mod.json 片段:
{
"type": "theme",
"ui_extensions": { "audio_level": "CustomWaveform.qml" }
}import QtQuick 2.15
Item {
id: root
anchors.fill: parent
property real level: 0.0
property var hostContext: null
// 若宿主未提供电平信号,可自行用 Connections 接 bridge(视版本)
Row {
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.margins: 8
spacing: 2
opacity: root.level > 0.01 ? 0.95 : 0.0
Repeater {
model: 5
Rectangle {
width: 2
height: Math.max(2, Math.min(10, root.level * 10))
color: "#00f0ff"
}
}
}
}完整可运行参考:extensions/example_custom_waveform_ui/、example_theme_cyberpunk/。
8. 设计与兼容建议
- 组件根上保留
anchors.fill: parent,避免撑破宿主布局。 - 所有
hostContext访问做空判断,便于预览。 - 不要依赖未在本文出现的全局对象名。
- 同一插槽同时只启用一个扩展;启用时会自动互斥。