外壳集成
模块可以没有界面,但照样能把数据放进宿主主界面。外壳有三块区域接受模块推送,协议统一:普通字段在前、按钮在后,_buttons 是保留键,停用或卸载后自动移除。
| 接口 | 展示位置 | 特点 |
|---|---|---|
ctx.set_card(payload) | 卡片区(每模块一张卡) | 摘要数据,随页面切换可见 |
ctx.push_fields(dict) | 底部字段条 | 常驻,实时关键数据 |
ctx.push_titlebar(dict) | 自绘标题栏 | 常驻,全局入口与按钮 |
三者都可在后台线程反复调用,外壳实时刷新。每次调用整体覆盖本模块此前内容,不是增量。
卡片区 set_card
payload 三种形态:
# ① 键值行:一张卡,逐行显示
ctx.set_card({"在线设备": 3, "平均电量": "72%"})
# ② 列表分组:每条一个分组(列表元素为 dict 时按键值行渲染)
ctx.set_card([
{"序列号": "ABC123", "状态": "已连接", "电量": "80%"},
{"序列号": "DEF456", "状态": "离线", "电量": "—"},
])
# ③ 标量:单个值直接显示
ctx.set_card("服务未启动")
# 清空(卡片消失)
ctx.set_card(None)值里嵌对象或数组会以 JSON 字符串显示,尽量用一层扁平的键值对。
底部字段条 push_fields
ctx.push_fields({"设备总数": 2, "在线": 1})
ctx.push_fields({}) # 清空本模块全部字段字段条适合放两三个最要紧的实时指标。渲染顺序固定:普通字段在前,_buttons 按钮在后。
标题栏注册 push_titlebar
在外壳标题栏注册全局入口,跨页面常驻可见:
def on_enable(self):
self.ctx.push_titlebar({
"在线": 128, # 普通字段:紧凑文本胶囊
"_buttons": [ # 保留键:按钮列表(渲染在字段之后)
{"label": "同步", "rpc": {"module": "my_module", "method": "sync"}},
{"label": "导出", "rpc": {"module": "my_module", "method": "export",
"args": ["csv"]}},
],
})
# 清除本模块全部标题栏项
self.ctx.push_titlebar({})协议约定:
| 约定 | 行为 |
|---|---|
| 渲染顺序 | 普通字段在前、_buttons 按钮在后 |
| 按钮执行 | 点击直接执行对应模块方法,不依赖模块页面 |
| 无 UI 模块 | 未声明 manifest.ui 的模块不渲染其 _buttons |
| 生命周期 | 模块停用/卸载后注册项自动移除,重新启用后由模块再注册 |
| 覆盖语义 | 每次调用覆盖本模块此前全部内容(非增量) |
清理习惯
停用和"无数据"两个状态下把推送清干净,不然主界面残留最后一次的旧数据:
def on_disable(self):
self.ctx.set_card(None)
self.ctx.push_fields({})
self.ctx.push_titlebar({})一个能说明三种推送的完整例子见 示例集 的轮询模块。