PythonIDE Docs
中文
简体中文

widget

Python 编写 WidgetKit 小组件:参数、状态、布局与发布到桌面。

用 Python 描述主屏、锁屏与 StandBy 小组件;由 PythonIDE + WidgetKit 负责渲染、刷新与桌面交互。

边界widgetWidgetKit 时间线模型,不是普通 App 页面。不要用 appui 做小组件,不要用 scene 做 60fps 游戏画布。脚本只描述布局、参数、状态与时间线,结尾必须 w.render()

#模块概览

说明
导入import widget
适合做什么计数器、进度、图表卡片、锁屏 accessory、可点按钮/开关
入口w = widget.Widget(...) → 组合节点 → w.render()(只创建一个 Widget
可调参数widget.param.text/color/number/slider/bool/choice/file — 预览面板可编辑
桌面交互widget.state.int/bool/...count.increment()done.toggle() 等 action
尺寸适配widget.contextwidget.family_value(...) 按 small/medium/large 分支
发布Widget Studio 运行后发布;文档 previewWidget 仅预览 → 从脚本到桌面

#快速开始

运行下面脚本会打开小组件预览(非 AppUI 全屏)。用环形图展示饮水进度,+ / 在桌面改写杯数。

预期效果:小组件预览面板显示与脚本一致的布局与交互。

python
import widget

goal = widget.param.number("每日杯数", 8, min=1, max=12)
glasses = widget.state.int("glasses", 0)
accent = widget.param.color("主色", "#38BDF8")

w = widget.Widget(background=("#F0F9FF", "#0C4A6E"), padding=14)
w.text("饮水打卡", size=16, weight="semibold").line_limit(1).min_scale(0.72)
w.ring_chart(
    min(int(glasses), int(goal)),
    total=int(goal),
    label=f"{int(glasses)}/{int(goal)} 杯",
    color=accent,
)
with w.row(spacing=10):
    (
        w.button("−", action=glasses.decrement(), style="plain")
        .line_limit(1)
        .min_scale(0.72)
    )
    (
        w.button("+", action=glasses.increment(), background=accent, color="#FFFFFF")
        .line_limit(1)
        .min_scale(0.72)
    )
w.render()

要点:

  • widget.param.number(...):预览里可调每日目标杯数。
  • widget.state.int(...) + ring_chart(...):桌面点击后环与标签同步刷新。
  • with w.row(...):横排多个按钮,比纵向堆叠更省高度。
  • .line_limit(1).min_scale(...):防止 small/medium 文字被裁切。

#Widget 预览示例

#每日一言(参数 + 尺寸分支)

纯展示卡片:无 widget.state,演示 param.textsymbolfamily_value;small 隐藏出处行。

预期效果:小组件预览面板显示与脚本一致的布局与交互。

python
import widget

quote = widget.param.text("名言", "专注一件事,做到极致。")
author = widget.param.text("出处", "— 佚名")
ink = widget.param.color("文字色", "#E2E8F0")
title_size = widget.family_value(17, small=15, large=20)
body_size = widget.family_value(15, small=13, large=17)

w = widget.Widget(background=("#0F172A", "#020617"), padding=16)
with w.row(spacing=8):
    w.symbol("quote.bubble.fill").color("#60A5FA").font_size(18)
    w.text("每日一言", size=14, weight="semibold", color="secondary").line_limit(1)
w.text(quote, size=body_size, color=ink).line_limit(3).min_scale(0.7)
if not widget.context.is_family("small"):
    w.text(author, size=12, color="secondary").line_limit(1).min_scale(0.72)
w.render()

#本周专注(折线图)

静态数据折线 + 可调曲线色;适合仪表盘类小组件,不涉及桌面点击。

预期效果:小组件预览面板显示与脚本一致的布局与交互。

python
import widget

title = widget.param.text("标题", "本周专注")
accent = widget.param.color("曲线色", "#6366F1")
minutes = [25, 40, 15, 50, 30, 45, 20]
chart_h = widget.family_value(48, small=36, large=56)

w = widget.Widget(background=("#F5F3FF", "#1E1B4B"), padding=14)
with w.row(spacing=8):
    w.symbol("brain.head.profile").color(accent).font_size(18)
    w.text(title, size=16, weight="semibold").line_limit(1).min_scale(0.72)
w.line_chart(minutes, color=accent, height=chart_h, fill=True)
if not widget.context.is_family("small"):
    w.text("分钟 / 天(示例数据)", size=11, color="secondary").line_limit(1)
w.render()

#心智模型

  1. 根容器w = widget.Widget(background=..., padding=..., style="clean") — 只管整体背景与边距。
  2. 内容节点textvaluesymbolimageprogressline_chart 等。
  3. 布局:多数卡片用 row() / column() / grid();精确定位才用 canvas() / table()
  4. 参数widget.param.* 在构建 UI 之前声明,供预览面板与 Studio 持久化。
  5. 状态widget.state.* 生成桌面可执行的 increment / toggle / set action。
  6. 上下文widget.context.familycontent_widthcontent_height 做尺寸分支。
  7. 收尾:脚本末尾有且仅有一次 w.render()

#与 appui / scene 怎么选

需求首选原因
主屏/锁屏/StandBy 卡片widgetWidgetKit 时间线与系统刷新预算
设置页、表单、导航 Appappui完整交互与滚动列表
触摸游戏、逐帧动画scene实时帧循环,不是 Widget 模型
教材海龟绘图turtle单次画布,非桌面组件

#WidgetKit 能做什么 / 不能做什么

适合不适合
静态/准静态展示、数字过渡动画文本输入框、长列表滚动
按钮、开关、链接(AppIntent)WebView、视频、复杂手势
时间线刷新、深色/透明/渐变背景60fps 实时动画、任意 Python 回调在扩展内执行

#API 参考

#速查

API作用
Widget(...)根容器;唯一入口
w.render()提交 IR,生成预览/桌面时间线
widget.param.text/color/number/slider/bool/choice/file用户可调参数
widget.state.int/float/bool/str/list持久状态 + action 工厂
count.increment() / done.toggle()按钮/开关的 action=
widget.context当前 family 与内容区尺寸
widget.family_value(d, small=..., large=...)按尺寸返回值
w.timeline(...)多条时间线条目(见专题文档)
widget.SMALL / MEDIUM / LARGE尺寸常量

#widget.param 声明

方法用途
text(name, default)标题、文案
color(name, default)十六进制或语义色
number(name, default, min=, max=)整数/小数参数
slider(name, default, min=, max=, step=)滑块
bool(name, default)开关类参数(预览面板,不是桌面 state)
choice(name, options, default=)下拉选项
file(name, default, extensions=)图片等资源路径

第一个参数 name 是参数 ID,同时作为预览面板默认标题。

#widget.state 与交互

python
count = widget.state.int("count", 0)
done = widget.state.bool("done", False)

w.button("加 1", action=count.increment())
w.button("减 1", action=count.decrement(by=2))
w.toggle("完成", state=done)  # 用 state=,不要手写 toggle action

状态 key 变更或删除后,需重新发布小组件,否则桌面可能仍读写旧 key。

#尺寸与布局

python
ctx = widget.context

if ctx.is_family("small"):
    w.text("简版", size=14)
elif ctx.is_family("large"):
    w.text("完整版", size=18)

size = widget.family_value(14, small=12, medium=14, large=18)

布局细节见 布局与尺寸;完整节点列表见 API 参考


#常见错误

错误写法后果修正
忘记 w.render()预览空白脚本末尾调用一次
创建多个 Widget()行为未定义只保留一个根 Widget
SpriteNode / appui.Button 混入脚本构建失败只用 widget.Widget 节点 API
按钮 action 写死字符串点击无反应widget.state.increment()
widget.param 写在 render() 之后参数面板缺失先声明参数再构建 UI
small 塞满 large 文案文字裁切family_value / is_family 分支 + line_limit
改 state key 不重新发布桌面计数错乱重新运行、发布,必要时删桌面组件重装
传 Python 函数给 action=需拉起 App 执行交互优先 widget.state;见 交互
w.symbol(..., color=, size=)TypeErrorw.symbol("name").color(c).font_size(n)
w.toggle(..., tint=)TypeErrorcolor=
w.link(..., icon=).line_limit()AttributeErroricon 的 link 不可链修饰符

#失败路径

情况处理
预览空白检查 w.render()、是否只创建一个 Widget、脚本是否混入 appui/scene
参数不出现确认 widget.param.* 在 UI 构建前,且 name 非空
点击没反应action 必须来自 widget.state;开关用 w.toggle(..., state=done)
桌面仍旧内容重新运行并发布;删除主屏小组件后重新添加
文本被裁切.line_limit(1).min_scale(0.65);small 隐藏次要行
预览与桌面不一致排错;确认已发布最新构建

#发布到桌面(简表)

文档里的 previewWidget 不能直接上主屏。完整步骤见 从脚本到桌面

  1. 把脚本复制到 Widget Studio 项目
  2. Studio 运行预览 → 调 widget.param → 切换 family 检查裁切
  3. 构建成功且提示「已发布」类消息
  4. 在 iOS 主屏幕 + 添加 Python IDE 小组件
  5. 在桌面点按钮/开关验证 widget.state

#专题文档

文档用途
从脚本到桌面发布流程与检查清单
布局与尺寸row/column/grid、family 预算
参数面板widget.param 详解
状态和交互state、按钮、开关、链接
时间线和动画timelinecontent_transition
资源与外观颜色、渐变、图片、SVG
排错预览/桌面不一致
API 索引按任务选 API
API 参考全部节点签名

#相关模块

文档用途
appui完整 App 界面(非小组件)
scene2D 游戏画布(非 WidgetKit)
shortcut快捷指令触发脚本刷新小组件

#相关文档

#预期效果

运行示例后,界面应出现文档描述的目标结果;若与预期不符,先看「失败路径」并按返回值或日志排查。