PythonIDE Docs
中文
简体中文

热重载

hot_reload 的启用方式、状态保留和调试边界。

appui.run(body_func, state=None, hot_reload=False, presentation='sheet')hot_reload=True 时监视调用脚本文件,保存后自动重新执行脚本并刷新界面,便于迭代 UI。body_func 可以写成 body(),也可以写成 body(state)


#预期效果

示例会展示热重载保留 State、刷新页面结构,并在错误时保持预览可恢复。

#启用方式

python
import appui

state = appui.State(count=0)


def increment():
    state.count += 1


def body():
    return appui.VStack([
        appui.Text(f"count = {state.count}").font("title2"),
        appui.Button("+1", action=increment)
            .button_style("bordered_prominent"),
    ], spacing=16).padding()

appui.run(body, state=state, hot_reload=True, presentation="sheet")

要点:

  • 监视的是 run() 调用栈所在文件inspect.stack),因此热重载入口应放在真实脚本中,而不是交互式 stdin
  • 保存文件后,运行环境会尽快重新加载脚本并刷新界面;触发速度取决于当前设备和文件系统。

#状态保留:仅 State 自动合并

热重载重新执行脚本后,若旧页面和新页面都使用 State,会按字段名保留仍然存在的状态值,从而让计数器、开关等继续保持当前值。

ReactiveState 不会自动合并到新实例;热重载后若脚本重新构造 ReactiveState(),字段会回到脚本初值,除非你在脚本里自行从文件恢复。

python
"""说明:热重载后 State 合并逻辑只针对 appui.State。"""
import appui

s = appui.State(a=1)
snapshot = s.to_dict()
assert snapshot["a"] == 1

(在应用内以 hot_reload=True 运行时可观察计数在保存后仍连续。)


#开发流程建议

  1. body 与小组件函数放在同一 .py 文件,run(..., hot_reload=True) 置于 if __name__ == "__main__": 中(若在应用内直接调用亦可)。
  2. 每次保存后,运行环境会重新读取当前文件并绑定新的 body
  3. 首帧会完整刷新界面树,避免旧界面结构影响新代码。

#出错时会发生什么

若新代码 语法错误导入失败,异常会显示在预览错误面板;进程不退出,修正后再保存即可。

python
import appui

state = appui.State(ok=True)

def body():
    return appui.VStack([
        appui.Text("保存本文件即可触发热重载").font("footnote"),
        appui.Button("关闭", action=appui.dismiss).button_style("bordered"),
    ], spacing=12).padding()

appui.run(body, state=state, hot_reload=True, presentation="sheet")

#调试技巧

  • 打印:保存后可在控制台观察重载成功或错误信息。
  • 按钮短暂不可点:保存瞬间正在替换回调,等界面刷新完成后再点一次。
  • 不要用 <stdin> 作为脚本路径:无法可靠监视;请使用磁盘上的 .py 文件运行。
  • presentation 组合fullscreen / fullscreen_with_close 同样支持热重载;关闭仍用 appui.dismiss()
python
import appui, inspect

def f():
    return appui.Text("x")

# 本段仅验证 run 的签名包含 hot_reload(不实际连接桥)
sig = inspect.signature(appui.run)
assert "hot_reload" in sig.parameters

#auto_refresh 的区别

特性hot_reload=Trueauto_refresh(interval)
触发条件源文件变更定时器周期
目的开发时替换代码时钟、轮询仪表盘
状态合并 State不重新加载模块
python
import appui
import time

state = appui.State()

def body():
    return appui.Text(time.strftime("%H:%M:%S")).font("title").padding()

appui.auto_refresh(interval=1.0)
appui.run(body, state=state, hot_reload=False, presentation="sheet")

#小结

  • hot_reload=True监视文件 → exec → 保留 State → 强制全量刷新
  • 适合 UI 布局与回调逻辑的快速迭代。
  • ReactiveState / 文件外缓存 需自行设计持久化策略。

更多运行器参数见 appui-ref-functions.md