PythonIDE Docs
中文
简体中文

快速上手

用四个可预览示例掌握 body、State、控件和导航。

这篇教程用四个可预览示例串起 AppUI 的最小闭环:显示页面、修改状态、编辑表单、列表进详情。每段都可以直接运行。

#1. Hello World

先让原生页面出现。body() 返回一个 View,脚本末尾调用 appui.run(body)

python
import appui


def body():
    return appui.NavigationStack(
        appui.VStack([
            appui.Text("Hello AppUI").font("title2").bold(),
            appui.Text("用 Python 编写原生 MiniApp 界面")
            .foreground_color("secondaryLabel"),
        ], spacing=8)
        .padding()
        .navigation_title("Hello")
    )


appui.run(body)

预期效果:预览显示一个带导航标题的原生页面,页面中有标题和说明文字。

#2. State 和按钮

State 保存页面数据。按钮回调修改状态后,页面会用新状态重建。

python
import appui

state = appui.State(count=0, message="Ready")


def decrease():
    state.batch_update(count=state.count - 1, message="Decreased")


def increase():
    state.batch_update(count=state.count + 1, message="Increased")


def body(view_state):
    return appui.NavigationStack(
        appui.VStack([
            appui.Text(f"当前计数:{view_state.count}").font("title3"),
            appui.HStack([
                appui.Button("-1", action=decrease).button_style("bordered"),
                appui.Button("+1", action=increase)
                .button_style("bordered_prominent"),
            ], spacing=12),
            appui.Text(view_state.message)
            .font("caption")
            .foreground_color("secondaryLabel"),
        ], spacing=16)
        .padding()
        .navigation_title("状态")
    )


appui.run(body, state=state)

预期效果:点击 +1-1 后计数和状态文案同步变化。

#3. 表单控件

设置页和编辑页优先使用 Form + Section。输入控件通过 on_change 写回 State

python
import appui

state = appui.State(name="Ada", enabled=False, volume=40.0, saved=False)


def set_name(value):
    state.batch_update(name=value, saved=False)


def set_enabled(value):
    state.batch_update(enabled=value, saved=False)


def set_volume(value):
    state.batch_update(volume=value, saved=False)


def save():
    state.saved = bool(state.name.strip())


def body():
    footer = "已保存" if state.saved else "修改后点击保存"
    return appui.NavigationStack(
        appui.Form([
            appui.Section("资料", [
                appui.TextField("姓名", text=state.name, on_change=set_name),
                appui.Toggle("启用提醒", is_on=state.enabled, on_change=set_enabled),
                appui.Slider(
                    value=state.volume,
                    minimum=0,
                    maximum=100,
                    on_change=set_volume,
                ),
            ], footer=footer),
            appui.Section("操作", [
                appui.Button("保存", action=save)
                .button_style("bordered_prominent"),
            ]),
        ]).navigation_title("表单")
    )


appui.run(body, state=state)

预期效果:修改文本、开关或滑块后页面保持响应;点击保存后底部文案变为“已保存”。

#4. 导航和列表

多页面 MiniApp 通常用 NavigationStack 包根页面,列表进详情用 NavigationLink。动态行必须有稳定 key。

python
import appui

items = [
    {"id": "docs", "title": "文档", "subtitle": "Guide"},
    {"id": "api", "title": "API", "subtitle": "Reference"},
    {"id": "demo", "title": "示例", "subtitle": "Cookbook"},
]

state = appui.State(last_opened="None")


def item_key(item):
    return item["id"]


def mark_opened(item):
    state.last_opened = item["title"]


def detail_view(item):
    def open_current():
        mark_opened(item)

    return appui.Form([
        appui.Section("详情", [
            appui.LabeledContent("标题", value=item["title"]),
            appui.LabeledContent("类型", value=item["subtitle"]),
            appui.Button("标记打开", action=open_current),
        ]),
        appui.Section("状态", [
            appui.LabeledContent("Last opened", value=state.last_opened),
        ]),
    ]).navigation_title(item["title"])


def row_view(item):
    label = appui.HStack([
        appui.Text(item["title"])
        .frame(max_width=appui.infinity, alignment="leading"),
        appui.Text(item["subtitle"]).foreground_color("secondaryLabel"),
    ])
    return appui.NavigationLink(destination=detail_view(item), label=label)


def body():
    return appui.NavigationStack(
        appui.List([
            appui.Section("入口", [
                appui.ForEach(items, row_builder=row_view, key=item_key),
            ])
        ]).navigation_title("列表")
    )


appui.run(body, state=state)

预期效果:列表显示三行入口,点击任一行进入详情页;详情页按钮会更新打开状态。

#发布前检查

检查项合格标准
入口脚本末尾只调用一次 appui.run(...)
呈现默认 presentation='sheet';全屏可用 'fullscreen''fullscreen_with_close'
页面body()body(state) 返回 AppUI View
状态回调修改 State,多字段更新用 batch_update(...)
按钮action 传命名函数,不写 action=save()
输入on_change 接收新值并写回 State
列表ForEach 使用稳定 key

#失败路径

  • 预览空白:确认 body() 返回 View,且脚本末尾调用了 appui.run(...)
  • 按钮没反应:确认 action 传函数本身,而不是函数调用结果。
  • 输入不更新:确认 on_change 的参数名接收新值,并写回 State
  • 列表详情错乱:确认 ForEach 使用稳定业务 id,不使用会变化的 index。
  • 页面越来越难维护:回到 AppUI UI 模式,先选页面结构。

#API 参考

继续查 AppUI API 地图。需要判断该用哪个运行时时,先看 运行时选择