Flet 应用启动核心:flet.run() 函数深度解析与实战指南
2026/9/24 13:56:15 网站建设 项目流程

Flet 应用启动核心:flet.run() 函数深度解析与实战指南

【免费下载链接】fletBuild realtime web, mobile and desktop apps in Python only. No frontend experience required.项目地址: https://gitcode.com/gh_mirrors/fl/flet

flet.run()是 Flet 框架中启动应用的统一入口:无论你的目标是桌面窗口、Web 服务还是移动端嵌入式运行,它都能根据参数与环境自动选择合适的传输通道并拉起应用。本指南以仓库 API 文档 run.md 所引用的flet.run为骨架,结合其实现源码 app.py,逐一拆解每个参数的含义、底层运行机制与环境变量,并给出可在当前仓库示例中直接验证的实战用法。

一、flet.run 在 Flet 中的定位

flet.run()是 Flet 应用的生命周期入口函数。它接收一个以Page为唯一参数的处理器(handler),在该处理器中你可以构建界面、绑定事件并执行业务逻辑,然后由run()负责与 Flet 客户端(桌面窗口、浏览器、移动端)建立连接、维护会话并驱动界面更新。

从源码看,run()定义于 sdk/python/packages/flet/src/flet/app.py,并通过 sdk/python/packages/flet/src/flet/init.py 以flet.run的名字暴露给用户。值得注意的是,Flet 1.0 采用 PEP 562 惰性导入策略(见__init__.py头部注释),import flet不再立即加载全部约 270 个模块,flet.run在首次访问时才被导入,因此直接使用ft.run(main)是零额外开销的。

最小可用示例

仓库示例应用大量采用ft.run(main)这种写法,例如 sdk/python/examples/apps/7guis/counter/main.py:

import flet as ft def main(page: ft.Page): page.title = "Counter" # ... 构建界面与事件处理 ... ft.run(main)

完整函数签名

def run( main: AppCallable, before_main: Optional[AppCallable] = None, name: str = "", host: Optional[str] = None, port: int = 0, view: Optional[AppView] = AppView.FLET_APP, assets_dir: Optional[str] = "assets", upload_dir: Optional[str] = None, web_renderer: WebRenderer = WebRenderer.AUTO, route_url_strategy: RouteUrlStrategy = RouteUrlStrategy.PATH, no_cdn: Optional[bool] = False, export_asgi_app: Optional[bool] = False, )

其中AppCallable是同步或异步回调的类型别名:它接受单个Page参数,返回值被忽略(见 app.py 中的定义)。

二、参数逐项详解

以下是flet.run()全部参数的说明与源码级解读(参数默认值与语义以 app.py 中的 docstring 为准):

参数类型默认值作用
mainAppCallable必填应用入口,接收一个Page参数的函数或协程
before_mainAppCallableNonePage创建之后、main执行之前调用
namestr""应用/页面名称,用于 Web 场景下的 URL 路径
hoststrNoneWeb 服务器绑定的主机/IP
portint0TCP 端口;为0时由系统自动选择可用端口
viewAppViewAppView.FLET_APP应用呈现模式(桌面窗口 / 浏览器等)
assets_dirstr"assets"应用资源目录路径
upload_dirstrNone上传文件保存目录
web_rendererWebRendererWebRenderer.AUTOWeb 渲染器类型
route_url_strategyRouteUrlStrategyRouteUrlStrategy.PATHURL 路由策略(pathhash
no_cdnboolFalse是否不从 CDN 加载 CanvasKit、Pyodide 与字体
export_asgi_appboolFalseTrue时返回配置好的 ASGI 应用而非运行事件循环

回调参数:main 与 before_main

  • main:应用入口。run()内部通过__get_on_session_created(app.py)构造会话回调,在该回调中依据处理器类型分派执行:
if inspect.iscoroutinefunction(main): await main(session.page) elif inspect.isasyncgenfunction(main): async for _ in main(session.page): await session.after_event(session.page) elif inspect.isgeneratorfunction(main): for _ in main(session.page): await session.after_event(session.page) else: main(session.page) # 同步函数 await session.after_event(session.page)

也就是说,main可以是普通同步函数、协程函数、异步生成器、同步生成器中的任意一种,框架都会正确处理并保证在处理器返回后调用session.after_event()刷新页面。若main抛出未捕获异常,框架会记录Unhandled error in main() handler日志并通过session.error()上报到客户端。

  • before_main:在Page创建后、main执行前运行的钩子,常用于注入依赖、初始化会话级状态。

name、host、port:Web 服务定位参数

  • name:页面名称,会拼接到 Web URL 路径中。实际生效值还受环境变量FLET_WEB_APP_PATH影响——当name为空而该环境变量非空时,以环境变量为准(见__get_page_name,app.py)。
  • host:Web 服务器绑定地址。源码中url_host = "127.0.0.1" if host in [None, "", "*"] else host,即默认绑定本机回环地址。
  • port0表示自动分配。在强制 Web 服务器模式下(force_web_server=True),若端口仍为0则使用8000(见 app.py)。

assets_dir 与 upload_dir:资源与上传目录

  • assets_dir默认值为常量DEFAULT_ASSETS_DIR = "assets"(app.py)。相对路径会基于当前脚本目录解析为绝对路径(export_asgi_app=True时则基于当前工作目录,见__get_assets_dir_pathrelative_to_cwd参数,app.py)。
  • 源码还兼容 PyInstaller "onefile" 打包场景:当"_MEI" in __file__时,相对路径基于可执行文件所在目录解析。
  • 若默认assets目录不存在,框架仅记录 debug 日志(不告警);若显式指定了不存在的目录,则记录assets_dir does not exist警告,并将该目录置空。
  • upload_dir同理支持相对路径解析(app.py)。
  • 两者均支持环境变量覆盖:FLET_ASSETS_DIR优先级最高,且永远不会被静默丢弃。

三、呈现模式:AppView 枚举

view参数控制应用以何种方式呈现。其可选值定义在 sdk/python/packages/flet/src/flet/controls/types.py:

枚举值字符串值行为
AppView.WEB_BROWSER"web_browser"以 Web 服务器方式运行,并自动在用户浏览器中打开
AppView.FLET_APP"flet_app"在 Flet 桌面窗口中运行(默认)
AppView.FLET_APP_WEB"flet_app_web"桌面窗口 + Web 服务器后端
AppView.FLET_APP_HIDDEN"flet_app_hidden"启动隐藏的 Flet 桌面窗口

桌面窗口模式的启动依赖flet_desktop包(run_async中通过ensure_flet_desktop_package_installed()按需确保安装,并调用open_flet_view_async打开窗口,见 app.py)。

四、Web 渲染器与路由策略

WebRenderer:Web 端渲染器选择

web_renderer用于 Web 托管场景,定义于 types.py:

  • AUTO(默认):由运行时自动选择。WebAssembly 构建下 Chromium 系浏览器优先使用 skwasm,其他浏览器回退到 CanvasKit;默认 Web 构建则始终使用 CanvasKit。
  • CANVAS_KIT:CanvasKit 渲染器,兼容性最好,是默认 Web 构建的标准渲染器;Flet 每次 UI 更新都会在 JavaScript 与 Dart 之间交换字节缓冲区,CanvasKit 在这种交换上显著更快。
  • SKWASM:仅 WebAssembly 构建可用,渲染性能可能更优,但跨 JS/Dart 边界的字节缓冲交换较慢,且需要浏览器与服务器满足 WebAssembly 及(多线程渲染时)SharedArrayBuffer 安全配置要求。

RouteUrlStrategy:URL 路由策略

route_url_strategy仅影响 Web 托管应用,定义于 types.py:

  • PATH(默认):路由存放在浏览器 pathname 中,URL 形如https://example.com/store。此策略通常要求 Web 服务器将未匹配的请求重写到index.html,以保证深链接与页面刷新可用。
  • HASH:路由存放在 URL 锚点片段中,URL 形如https://example.com/#/store。当无法配置托管服务器做 pathname 重写时,该策略是实用之选。

五、底层运行机制:四种传输通道的自动选择

flet.run()最终调用asyncio.run(run_async(...))(app.py)。在run_async内部(app.py),传输通道按以下优先级选择:

is_pyodide() 且非嵌入式 → PyodideConnection(浏览器内嵌执行) FLET_DART_BRIDGE_PORT 且嵌入式 → dart_bridge 进程内传输 嵌入式,或 view ∈ {FLET_APP, FLET_APP_HIDDEN, None} 且未强制 Web → Socket 服务器 其余情况 → FastAPI/uvicorn Web 服务器
  1. Pyodide 通道:在浏览器内直接运行 Python(is_pyodide()为真时),通过PyodideConnection建立连接(app.py)。
  2. dart_bridge 进程内通道:嵌入式场景下设置FLET_DART_BRIDGE_PORT时启用(app.py)。它与 Socket 服务器使用相同的 MsgPack 帧协议,但通过进程内字节通道传输,省去了 socket 文件与内核上下文切换。从源码注释可见,Android 进程复用场景下_DartBridgeServerHandle会通过dart_bridge.add_session_restart_handler监听 Dart VM 重启,并透明地在新端口上重建连接。
  3. Socket 服务器:桌面/嵌入式模式默认通道(FletSocketServer),支持FLET_SERVER_UDS_PATH环境变量指定 Unix Domain Socket(app.py)。
  4. Web 服务器:基于 FastAPI/uvicorn,由flet_web包中的serve_fastapi_web_app提供服务(app.py),负责加载 Web 前端、处理页面 URL、资源与上传目录。

此外,run_async为桌面/Web 进程注册了SIGINTSIGTERM信号处理器,收到信号后通过terminate事件请求优雅退出,并在finally中确保关闭连接(app.py)。

六、环境变量一览

flet.run()/run_async()的行为受以下环境变量影响(均可在 app.py 源码中核实):

环境变量作用
FLET_FORCE_WEB_SERVER为真时强制使用 Web 服务器模式(等价于view=WEB_BROWSER
FLET_SERVER_PORT覆盖 Web 服务器端口
FLET_SERVER_IP覆盖 Web 服务器绑定主机
FLET_SERVER_UDS_PATHSocket 服务器改用 Unix Domain Socket
FLET_WEB_APP_PATH覆盖name参数,决定 Web URL 路径段
FLET_ASSETS_DIR覆盖assets_dir(优先级最高)
FLET_DISPLAY_URL_PREFIX应用启动时按prefix + page_url + view打印 URL,且不再自动打开浏览器
FLET_DART_BRIDGE_PORT嵌入式场景启用进程内 dart_bridge 通道
FLET_LOG_LEVEL设置日志级别;flet run -v即通过该变量让框架日志输出到控制台

其中FLET_FORCE_WEB_SERVER在 Linux 服务器环境(is_linux_server())下会被自动置真,这是桌面窗口在无显示服务环境下无法启动时的兜底行为(app.py)。

七、run 与 run_async:同步与异步入口

flet.run()flet.run_async()是一对孪生入口(后者文档位于 run_async.md),区别在于:

  • run():同步 API,内部用asyncio.run()包装run_async,适合在脚本__main__块中直接调用,也是仓库示例(如 7guis、cookbook 等)的标准写法。
  • run_async():协程 API,须在既有事件循环中await,适合集成到异步应用(如 FastAPI、异步测试框架)中。其参数与run()完全一致,但没有export_asgi_app参数
  • 两者都接受字符串形式的枚举参数(如view="web_browser"),内部通过AppView(...)WebRenderer(...)RouteUrlStrategy(...)自动完成类型转换。

在既有事件循环中嵌入:export_asgi_app

export_asgi_app=Truerun()独有的集成模式:此时run()不会启动事件循环,而是返回一个配置好的 FastAPI ASGI 应用(依赖flet_web包中的get_fastapi_web_app,见 app.py)。这使 Flet 页面能够直接挂载到用户自己的 FastAPI/ASGI 服务器中,与已有的路由、中间件共存。该模式下资源路径基于当前工作目录解析,适用于服务器端部署。

八、实战模式小结

结合仓库示例与源码行为,可总结出以下常用模式:

  1. 桌面应用(默认):ft.run(main)view保持AppView.FLET_APP,自动启动 Flet 桌面窗口。
  2. 浏览器运行ft.run(main, view=ft.AppView.WEB_BROWSER),启动 Web 服务器并打开浏览器;亦可通过flet runCLI 配合--web等选项达成(参见 CLI 文档)。
  3. 无界面服务端:设置FLET_FORCE_WEB_SERVER=1,或使用host="0.0.0.0"让外部设备可访问;多用户场景下建议结合 FastAPI 集成文档 使用export_asgi_app=True托管。
  4. 异步应用:在协程中await ft.run_async(main, ...),支持async def main(page)乃至异步生成器形式的处理器。
  5. Pyodide/嵌入式run()自动检测 Pyodide 环境与FLET_DART_BRIDGE_PORT,无需额外代码即可在浏览器内或嵌入式宿主中运行。

九、延伸阅读与源码导航

  • API 文档骨架:run.md(由 CrocoDocs 组件从 docstring 生成,生成管线见 tools/crocodocs/src/crocodocs/generate.py)
  • 核心实现:sdk/python/packages/flet/src/flet/app.py
  • 枚举类型定义:sdk/python/packages/flet/src/flet/controls/types.py
  • 异步入口文档:run_async.md
  • 真实调用示例:sdk/python/examples/apps/7guis/counter/main.py
  • 入口相关教程:running-app.md
  • 打包部署参考:packaging 相关文档

【免费下载链接】fletBuild realtime web, mobile and desktop apps in Python only. No frontend experience required.项目地址: https://gitcode.com/gh_mirrors/fl/flet

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询