跳到主要内容

Flet v0.25.0 版本发布公告

· 阅读需 16 分钟
Feodor Fitsner
Flet 创始人及开发者

嘿,Flet 开发者们,我们有一些令人兴奋的消息要分享——Flet 0.25.0 正式发布了!

最大的新闻是什么呢?iOS 和 Android 打包不再依赖 Kivy 了。不再需要处理令人沮丧的 Python 二进制依赖关系——Flet 现在使用其自己的自定义 Python 运行时,因此您的应用构建比以往任何时候都更容易。此外,我们还添加了许多新功能,如更好的权限控制、更快的重建,甚至还有一个轻量级的 Linux 客户端,避免了臃肿。

让我们深入了解 Flet 0.25.0 所提供的所有酷炫功能吧!🚀

如何升级

运行以下命令来升级 Flet:

pip install 'flet[all]' --upgrade
备注

[all] 是一个“额外”的指定符,它告诉 pip 安装所有 flet 包的依赖项。请参阅下面的新的 Python 包结构部分以了解解释。

requirements.txtpyproject.toml 中将 flet 包版本提升到 0.25.0(或者完全删除它以使用最新版本)。

新的打包方式

Flet 针对 iOS 和 Android 的打包一直依赖于 Kivy,当您的应用依赖于 Python 二进制包(如 Numpy 或 Pillow)时,这会非常烦人。您需要使用 Kivy 命令行工具自己编译这些包。如果 Kivy 没有某些包(如 Pydantic)的“配方”,那真的会让人感到沮丧甚至绝望。

Flet 不再依赖 Kivy,而是使用其自己在内部精心制作的 Python 运行时。

Flet 针对 iOS 和 Android 的打包实现遵循了 PEP 730(iOS)和 PEP 738(Android)中定义的严格规范,这些规范在 Python 3.13 中实现并发布(并回溯到 Python 3.12)。当 pypi.org 支持 iOS 和 Android 的 wheel 标签,并且第三方 Python 包维护者开始上传他们的移动包时,Flet 将与它们兼容,您将能够在您的 Flet 应用中使用它们。

预构建的二进制包

针对 iOS 和 Android 的 flet build 命令现在从 https://pypi.flet.dev 安装预构建的二进制包。

可以通过在 Mobile Forge 项目中创建配方来构建新的包。目前,Flet 团队正在为您编写这些配方,但当该过程经过完善并完全自动化后,您将能够发送 PR 并立即测试编译后的包。

如果您在 https://pypi.flet.dev 上还没有看到您需要的包,您可以在 Flet 讨论 - 包 中提出请求。请不要请求纯 Python 包。在 https://pypi.org 上转到包的“下载文件”部分,并确保它包含特定于二进制平台的 wheel。

打包行为也发生了变化:

  • 打包不再尝试将 flet 依赖替换为 flet-runtimeflet-embedflet-pyodide,而是从 requirements.txtpyproject.toml 中“按原样”安装所有依赖项——这要归功于新的 Flet 包结构
  • 如果未找到目标平台的二进制包,打包将不会尝试从源分布进行编译,而是会以有意义的错误失败。

Python 3.12

打包的 Flet 应用在所有平台上都在 Python 3.12.7 运行时上运行。

权限

新的 flet build 命令允许对嵌入到 AndroidManifest.xmlInfo.plist.entitlements 文件中的权限、功能和授权进行精细控制。

这些文件中不再有硬编码的权限!

例如,为 iOS 捆绑包设置权限:

flet build --info-plist NSLocationWhenInUseUsageDescription="此应用在使用时使用位置服务。"

或者在 pyproject.toml 中进行相同的设置(请阅读下文关于 pyproject.toml 支持的内容):

[tool.flet.ios.info] # --info-plist
NSLocationWhenInUseUsageDescription = "此应用在使用时会使用定位服务。"

设置 Android 权限和功能的示例:

flet build \
--android-permissions android.permission.READ_EXTERNAL_STORAGE=True \
android.permission.WRITE_EXTERNAL_STORAGE=True \
--android-features android.hardware.location.network=False

在文档中阅读更多关于权限的内容

对应用编译和清理的控制

默认情况下,flet build 命令不再将应用的 .py 文件编译为 .pyc 文件,这使您能够推迟发现应用中的任何语法错误并完成打包。

您可以使用以下新选项来控制编译和清理:

  • --compile-app - 编译应用的 .py 文件。
  • --compile-packages - 编译已安装包的 .py 文件。
  • --cleanup-on-compile - 在成功编译后删除不必要的文件。

为 Android 捆绑包签名

我们还为 Android 构建添加了新的签名选项:

  • --android-signing-key-store - Android 应用的上传密钥库 .jks 文件的路径。
  • --android-signing-key-store-password - Android 签名存储密码。
  • --android-signing-key-alias - Android 签名密钥别名。默认是 "upload"。
  • --android-signing-key-password - Android 签名密钥密码。

阅读 构建和发布 Android 应用,以获取有关如何为 Android 构建配置上传密钥的更多信息。

深度链接配置

有一个新的 --deep-linking-url 选项可用于为 iOS 和 Android 构建配置深度链接。该值必须采用 <sheme>://<host> 的格式。

更快的重新构建

flet build 命令创建的临时 Flutter 应用不再在每次构建时在临时目录中重新创建,而是缓存在 build/flutter 目录中,这使得重新构建更快,改善了打包故障排除,并且不会污染用户的临时目录。

不过,您可以使用 --clear-cache 选项进行干净的构建。

按 ABI 拆分 APK

flet build 现在提供了内置的 --split-per-abi 选项,以按 ABI 拆分 APK。

应用的“数据”和“临时”目录

Flet 开发人员一直在询问在哪里存储应用数据,例如上传的文件、SQLite 数据库等,这些数据在应用更新期间是持久的。

此版本引入了两个在您的 Flet 应用中可用的环境变量:

  • FLET_APP_STORAGE_DATA - 用于存储在应用更新之间保留的应用数据的目录。该目录已经预先创建,其位置取决于应用运行的平台。
  • FLET_APP_STORAGE_TEMP - 用于临时应用文件(即缓存)的目录。该目录已经预先创建,其位置取决于应用运行的平台。

例如,您可以在应用中按如下方式读取数据文件夹路径:

import os

# 在 Web 模式下运行应用时,它为 `None`
data_dir = os.getenv("FLET_APP_STORAGE_DATA")

:::注意 flet run 命令会创建数据和临时目录,并将 FLET_APP_STORAGE_DATAFLET_APP_STORAGE_TEMP 设置为它们的路径。 :::

pyproject.toml 支持

将所有 flet build 设置作为命令行选项携带是不方便且繁琐的。

在 Flet 0.25.0 版本中,现在可以在 pyproject.toml 中配置 flet buildflet runflet publish 设置!

Flet 会在 pyproject.toml 中添加 tool.flet 部分和子部分。以下是您可以放入应用根文件夹的 pyproject.toml 的最小版本:

[project]
name = "my_app"
version = "1.0.0"
description = "我的第一个 Flet 项目"
authors = [
{name = "John Smith", email = "john@email.com"}
]
dependencies = ["flet"]

您还可以使用 flet create 命令为您的项目生成一个起始的 pyproject.toml(以及其他文件)。

新的 Python 包结构

我们对 Flet Python 包进行了重构,并移除了 flet-coreflet-runtimeflet-embedflet-pyodide 包。

新的结构避免了在各种平台上安装 flet 包时重写 pip 依赖项。如果 flet 不是用户应用程序的直接依赖项,那么在安装时就会存在检测要安装的正确 flet 包(flet-runtimeflet-embedflet-pyodide?)的问题。

新的 Flet 包:

  • flet - 进行最小 Flet 设置所需,是各种平台的应用程序入口点,包含核心逻辑和控件。在所有平台上安装。
  • flet-cli - 包含 Flet CLI 命令。仅在桌面端安装。
  • flet-desktop - 包含适用于 macOS、Windows 和 Linux 的预构建 Flet“客户端”应用程序二进制文件。默认情况下仅在 macOS 和 Windows 桌面上安装。
  • flet-desktop-light - 包含适用于 Linux 的轻量级版本(不含音频和视频控件)的 Flet“客户端”。默认情况下仅在 Linux 桌面上安装。
  • flet-web - 包含 Flet Web“客户端”和 FastAPI 集成。仅在桌面端安装。

打包的 Flet 应用现在只包含 flet 包。

flet 包的额外功能

flet 包定义了以下额外功能,在使用 pip、uv、poetry 和其他包管理器安装 Flet 时可以指定:

  • flet[all] - 安装 fletflet-cliflet-desktopflet-web。推荐用于开发。
  • flet[cli] - 安装 fletflet-cli。可在 CI 环境中仅用于打包。
  • flet[web] - 安装 fletflet-web。用于部署 Flet Web 应用。
  • flet[desktop] - 安装 fletflet-desktop。用于仅桌面端的开发。

新的 Flet 安装和升级命令

从此版本开始,flet 包的开发版本应使用以下命令安装:

pip install 'flet[all]'

升级 flet 包:

pip install 'flet[all]' --upgrade

:::注意 pip install flet 仍然可以使用,但它将仅安装 flet 包,而依赖包将根据需要进行安装。例如,当您运行任何 flet CLI 命令时,将安装 flet-cli,或者当您运行 flet run 命令时,将安装 flet-desktop 包。 :::

Linux 的“轻量级”客户端

默认情况下,现在在 Linux 上安装的是一个不含音频和视频控件的轻量级桌面客户端。这改善了初始用户体验,因为用户不需要立即处理 gstreamer(音频)和 mpv(视频)的依赖项,Flet “即可正常工作”。

一旦用户获得了一些 Flet 经验并希望在其应用程序中使用视频和音频控件,他们可以安装 gstreamer 和/或 mpv,并将 Flet 桌面客户端替换为完整版本。

卸载“轻量级”Flet 客户端:

pip uninstall flet-desktop-light --yes

安装完整的 Flet 桌面客户端:

pip install flet-desktop

新控件

  • 移动广告(BannerInterstitial)(详细信息和示例)。
  • Button 控件(#4265) - 它只是 ElevatedButton 控件的别名。

重大变更

  • Badge 控件重构为数据类;向所有控件添加了新的 badge 属性(#4077)。

以下是如何迁移:

# 之前
page.navigation_bar = ft.NavigationBar(
destinations=[
ft.NavigationBarDestination(
icon_content=ft.Badge(
content=ft.Icon(ft.Icons.PHONE),
text=10,
),
label="Calls",
),
]
)

# 之后
page.navigation_bar = ft.NavigationBar(
destinations=[
ft.NavigationBarDestination(
icon=ft.Icon(
ft.Icons.PHONE,
badge="10",
),
label="Calls",
),
]
)

其他变更

新增内容

  • TextField.counter_text 中添加了 {value_length}{max_length}{symbols_left} 占位符(#4403)。
  • 在构建命令行界面(cli)命令中添加了 --skip-flutter-doctor#4388)。
  • 增强了 WebView#4018)。
  • 增强了 Map 控件(#3994)。
  • 暴露了更多的 Theme 属性(#4278#4278)。
  • 在多个控件中暴露了更多属性(#4105)。
  • 在类似容器的控件中添加了 __contains__ 方法(#4374)。
  • 添加了自定义的 Markdown 代码主题(#4343)。
  • 为对话框添加了 barrier_color 属性(#4236)。
  • iconicon_content 属性合并为 icon: str | Control#4305)。
  • colorsicons 变量迁移到枚举类型(Enums)中(#4180)。
  • TextFieldsuffix_iconprefix_iconicon 可以是 Controlstr#4173)。
  • flet pack CLI 命令添加了 --pyinstaller-build-args#4187)。
  • 使 SearchBar 的视图高度可调节;添加了新的属性(#4039)。
  • 提升了 Rive 版本并修复了 rive_common 的 Linux 应用构建模板。

Bug 修复

  • 修复了 Icon 的旋转问题(#4384)。
  • 修复了使用 MarkdownCodeTheme 枚举时 Markdown.code_theme 的回归问题(#4373)。
  • 修复了 SegmentNavigationBarDestination 仅接受字符串工具提示的问题(#4326)。
  • date 格式错误时显示信息性消息(#4019)。
  • 修复了 MapConfiguration.interaction_configuration 未被遵守的问题(#3976)。
  • 修复了 Video.jump_to() 在使用负索引时失败的问题(#4294)。
  • 修复了 AppBar.tooltip_opacity 中的条件问题(#4280)。
  • 修复了错误的类型(asyncio.Futureconcurrent.futures.Future)并处理了 CancelledError#4268)。
  • 修复了点击 CupertinoContextMenuAction 时上下文菜单未关闭的问题(#3948)。
  • 修复了下拉菜单的 max_menu_height 问题(#3974)。
  • 修复了在 before_update() 中防止按钮样式被修改的问题(#4181)。
  • 修复了禁用填充按钮在视觉上未被尊重的问题(#4090)。
  • 当设置了 label 时,为 Row 使用 MainAxisSize.min#3998)。
  • 修复了 NavigationBarDestination.disabled 没有视觉效果的问题(#4073)。
  • 修复了 CupertinoTextField 中的自动填充问题(#4103)。
  • Linechart:在显示之前对工具提示进行 jsonDecode#4069)。
  • 修复了按钮的 bgcolorcolorelevation#4126)。
  • 修复了 Windows 上的滚动问题(#4145)。
  • 如果 no_rich_outputTrue,则在 Windows 上跳过运行 flutter doctor#4108)。
  • 修复了 TextField 在 Linux Mint 上冻结的问题(#4422)。

结论 Flet 0.25.0 是一个重大版本,非常欢迎您的反馈!

升级到 Flet 0.25.0,测试您的应用程序,并告诉我们您对我们添加的新功能的看法。

如果您有任何问题,请加入Flet Discord 服务器或在Flet GitHub 讨论区创建一个新主题。 快乐地进行 Flet 开发!👾

pyproject.toml 对 flet 构建命令的支持

· 阅读需 8 分钟
Feodor Fitsner
Flet 的创始人和开发者

随着时间的推移,flet build 命令的选项数量大幅增加,在命令行中携带所有这些设置变得不方便。

今天,我们很高兴地宣布另一个 Flet 预发布版本,现在可以在 pyproject.toml 中配置应用程序构建设置!

安装预发布版本

pip install flet==0.25.0.dev3526
备注

出于测试目的,我们建议在专用的 Python 虚拟环境中安装 Flet 预发布版本。

使用预发布版本构建应用程序

要使用 flet build 命令和 Flet 的预发布版本构建您的应用程序,请确保您的 requirements.txt 要么包含确切的版本说明符:

flet==0.25.0.dev3526

要么在 flet 依赖项之前加上 --pre 标志:

--pre
flet

快速开始

在您的 Flet 应用程序的根目录中创建以下最小的 pyproject.toml 文件,或者运行 flet create 从模板创建一个新的应用程序:

[project]
name = "my_app"
version = "1.0.0"
description = "我的第一个 Flet 项目"
authors = [
{name = "John Smith", email = "john@email.com"}
]
dependencies = ["flet==0.25.0.dev3526"]
备注

使用 pyproject.toml 后,您不再需要 requirements.txt。但是,如果应用程序目录中存在 requirements.txt 文件,flet build 命令将优先从该文件中读取依赖项,而不是从 pyproject.toml 中列出的依赖项。

[project]project.toml 的标准必填部分。

备注

Flet 还支持由 Poetry 创建的包含项目设置的 [tool.poetry] 部分。

flet build 命令也支持的 Poetry 的最小 pyproject.toml 如下:

[tool.poetry]
name = "my_app"
version = "1.0.0"
description = "我的第一个 Flet 项目"
authors = ["John Smith <john@email.com>"]

[tool.poetry.dependencies]
python = "^3.10"
flet = "0.25.0.dev3526"

project.name(或 tool.poetry.name)对应于 flet build 命令的 --project 选项,它将是应用程序包或可执行文件的名称。project.name 的值将进行“slugify”处理,其中所有非字母数字值将被替换为破折号 -

project.version(或 tool.poetry.version)对应于 --build-version 选项,它是一个 "x.y.z" 字符串的值,用作向用户显示的版本号。

project.description(或 tool.poetry.description)对应于 --description 选项,它是用于可执行文件或包的描述。

备注

project.authorstool.poetry.authors 不会被 flet build 使用,但这是标准和其他工具所要求的。

用 CLI 选项覆盖配置

pyproject.toml 中的所有设置都有相应的 flet build CLI 选项。如果您运行 flet build 命令并指定已经在 pyproject.toml 中配置的选项,CLI 选项的值将覆盖配置文件中的值。

项目依赖项

project.dependencies 部分列出项目依赖项。该值是一个带有类似 pip 的需求说明符的数组:

[project]
dependencies = [
"flet==0.25.0.dev3526",
"numpy"
]

产品信息

所有特定于 Flet 的设置都应放入 [tool.flet] 部分及其下面的子部分中。

产品信息设置补充了 [project] 部分中的设置,并允许配置应用程序包标识符和产品显示名称。

[tool.flet]
org = "com.mycompany" # --org
product = "产品名称" # --product
company = "我的公司" # --company
copyright = "版权所有 (C) 2024 年,我的公司" # --copyright
build_number = 1 # --build-number

应用程序包内容

以下设置控制 Python 应用程序归档的内容以及应用程序/包源的编译。

[tool.flet]
app.module = "main" # --模块名称
app.path = "src" # 相对于 `pyproject.toml` 的 Python 应用程序的路径
app.exclude = ["assets"] # --排除

compile.app = false # --编译应用程序
compile.packages = false # --编译包
compile.cleanup = false # --编译时清理

它们也可以在各自的子部分下写成如下形式:

[tool.flet.app]
module = "main"
path = "src"
exclude = ["assets"]

[tool.flet.compile]
app = false
packages = false
cleanup = false

启动画面(Splash)

[tool.flet.splash]
color = "" # --启动画面颜色
dark_color = "" # --深色启动画面颜色
web = false # --无网页启动画面
ios = false # --无 iOS 启动画面
android = false # --无 Android 启动画面

权限

[tool.flet]
permissions = ["camera", "microphone"] # --权限

深度链接

[tool.flet.deep_linking]
scheme = "https" # --深度链接方案
host = "mydomain.com" # --深度链接主机

Android 设置

[tool.flet.android]
adaptive_icon_background = "" # --Android 自适应图标背景
split_per_abi = false # --按 ABI 拆分

权限(注意键名周围的引号 "):

[tool.flet.android.permission]  # --Android 权限
"android.permission.CAMERA" = true
"android.permission.CAMERA" = true

功能(注意键名周围的引号 "):

[tool.flet.android.feature]  # --Android 功能
"android.hardware.camera" = false

Android 特定的深度链接:

[tool.flet.android.deep_linking]
scheme = "https" # --深度链接方案
host = "mydomain.com" # --深度链接主机

Android 捆绑包签名选项:

[tool.flet.android.signing]
# 可以使用 `--android-signing-key-store-password` 和 `--android-signing-key-password` 选项或
# FLET_ANDROID_SIGNING_KEY_STORE_PASSWORD 和 FLET_ANDROID_SIGNING_KEY_PASSWORD 环境变量传递存储和密钥密码。
key_store = "path/to/store.jks" # --Android 签名密钥存储
key_alias = "upload"

iOS 设置

[tool.flet.ios]
team = "team_id" # --团队

[tool.flet.ios.info] # --信息列表
NSCameraUsageDescription = "此应用程序使用相机来..."

[tool.flet.ios.info.deep_linking]
scheme = "https"
host = "mydomain.com"

macOS 设置

[tool.flet.macos]
entitlement."com.apple.security.personal-information.photos-library" = true
[tool.flet]
build_arch = "arm64" # --架构 - 如果未指定架构,Flet 将为 arm64 和 x86_64 架构构建通用包

Web 设置

[tool.flet.web]
base_url = "/" # --基础 URL
renderer = "canvaskit" # --Web 渲染器
use_color_emoji = false # --使用彩色表情符号
route_url_strategy = "path" # --路由 URL 策略

Flutter 设置

依赖项

flutter.dependencies = ["flet_video", "flet_audio"]  # --包含包

或者使用带有版本的替代语法:

[tool.flet.flutter.dependencies]
flet_video = "1.0.0"
flet_audio = "2.0.0"

或者使用磁盘上包的路径:

[tool.flet.flutter.dependencies.my_package]
path = "/path/to/my_package"

额外的构建参数

flutter.build_args = ["--some-flutter-arg"] # --Flutter 构建参数

额外的 pubspec.yaml 设置

允许将任意内容注入到生成的 pubspec.yaml 中,例如:

[tool.flet.flutter.pubspec.dependency_overrides]
web = "1.0.0"

自定义模板

[tool.flet.template]
path = "gh:some-github/repo" # --模板
dir = "" # --模板目录
ref = "" # --模板引用

就是这样!升级到 Flet 0.25.0.dev3526,尝试这个新功能并告诉我们您的想法! 干杯!

Flet 新打包预发布

· 阅读需 11 分钟
Feodor Fitsner
Flet 创始人及开发者

Flet 针对 iOS 和 Android 的打包一直依赖于 Kivy,当您的应用依赖于 Python 二进制包(如 Numpy 或 Pillow)时,这会非常烦人。您需要使用 Kivy 命令行工具自己编译这些包。如果 Kivy 对于某些包(如 Pydantic)没有“配方”,那真的会让人感到沮丧甚至绝望。

不再需要 Kivy 了!我们刚刚发布了 Flet 0.25.0.dev3519 预发布版本,其中改进的 flet build 命令不再使用 Kivy!Flet 现在使用其自己的“精心内部制作”的 Python 运行时。

Flet 针对 iOS 和 Android 的打包实现遵循了 PEP 730(iOS)和 PEP 738(Android)中定义的严格规范,这些规范在 Python 3.13 中实现并发布(并回溯到 Python 3.12)。当 pypi.org 支持 iOS 和 Android 的 wheel 标签,并且第三方 Python 包维护者开始上传他们的移动包时,Flet 将与它们兼容,您将能够在您的 Flet 应用中使用它们。

安装预发布版本

pip install flet==0.25.0.dev3519
备注

出于测试目的,我们建议在专用的 Python 虚拟环境中安装 Flet 预发布版本。

使用预发布版本构建应用

要使用 flet build 命令和 Flet 的预发布版本构建您的应用,请确保您的 requirements.txt 要么包含确切的版本说明符:

flet==0.25.0.dev3519

要么在 flet 依赖项之前使用 --pre 标志:

--pre
flet

Python 3.12

打包的 Flet 应用在所有平台上都运行在 Python 3.12.6 运行时上。

预构建二进制包

针对 iOS 和 Android 的 flet build 命令现在从 https://pypi.flet.dev 安装预构建的二进制包。

可以通过在 Mobile Forge 项目中创建配方来构建新包。目前,Flet 团队正在为您编写这些配方,但当该过程得到完善并完全自动化后,您将能够发送 PR 并立即测试编译后的包。

如果您在 https://pypi.flet.dev 上还没有看到某个包,您可以在 Flet 讨论 - 包 中请求。请不要请求纯 Python 包。在 https://pypi.org 上转到包的“下载文件”部分,并确保它包含特定于二进制平台的 wheel。

打包行为也发生了变化:

  • 打包不再尝试将 flet 依赖项替换为 flet-runtimeflet-embedflet-pyodide,而是从 requirements.txtpyproject.toml 中“按原样”安装所有依赖项 - 这要归功于新的 Flet 包结构(链接)。
  • 如果未找到目标平台的二进制包,打包将不会尝试从源分布中编译它,而是会以有意义的错误失败。

新的包结构

该结构避免了在各种平台上安装 flet 包时重写 pip 依赖项。如果 flet 不是用户应用中的直接依赖项,则存在检测要安装的正确 flet 包(flet-runtimeflet-embedflet-pyodide?)的问题。

新的 Flet 包:

  • flet - 进行最小 Flet 设置所需,是各种平台的应用入口点。在所有平台上安装。
  • flet-core - 进行最小 Flet 设置所需,包含核心逻辑和控件。在所有平台上安装。
  • flet-cli - 包含 Flet CLI 命令。仅在桌面上安装。
  • flet-desktop - 包含适用于 macOS、Windows 和 Linux 的预构建 Flet“客户端”应用二进制文件。默认情况下仅在 macOS 和 Windows 桌面上安装。
  • flet-desktop-light - 包含适用于 Linux 的轻量级版本(不含音频和视频控件)的 Flet“客户端”。默认情况下仅在 Linux 桌面上安装。
  • flet-web - 包含 Flet Web“客户端”和 FastAPI 集成。仅在桌面上安装。

换句话说,打包的 Flet 应用仅包含 fletflet-core 包。

Linux 的“轻量级”客户端

默认情况下,不含音频和视频控件的轻量级桌面客户端不会在 Linux 上安装。这改善了初始用户体验,因为用户不需要立即处理 gstreamer(音频)和 mpv(视频)依赖项,Flet“就能正常工作”。

一旦用户获得了一些 Flet 经验并希望在其应用中使用视频和音频控件,他们可以安装 gstreamer 和/或 mpv,并将 Flet 桌面替换为完整版本。

卸载“轻量级”Flet 客户端:

pip uninstall flet-desktop-light --yes

安装完整的 Flet 桌面客户端:

pip install flet-desktop==0.25.0.dev3519

权限

新的 flet build 命令允许对嵌入到 AndroidManifest.xmlInfo.plist.entitlements 文件中的权限、功能和授权进行精细控制。

这些文件中不再有硬编码的权限!

iOS

设置 iOS 权限:

flet build --info-plist permission_1=True|False|description permission_2=True|False|description...

例如:

flet build --info-plist NSLocationWhenInUseUsageDescription=This app uses location service when in use.

macOS

设置 macOS 授权:

flet build --macos-entitlements name_1=True|False name_2=True|False...

默认的 macOS 授权:

  • com.apple.security.app-sandbox = False
  • com.apple.security.cs.allow-jit = True
  • com.apple.security.network.client = True
  • com.apple.security.network.server" = True

Android

设置 Android 权限和功能:

flet build --android-permissions permission=True|False... --android-features feature_name=True|False

例如:

flet build \
--android-permissions android.permission.READ_EXTERNAL_STORAGE=True \
android.permission.WRITE_EXTERNAL_STORAGE=True \
--android-features android.hardware.location.network=False

默认的 Android 权限:

  • android.permission.INTERNET

可以使用 --android-permissions 选项和 False 值禁用默认权限,例如:

flet build --android-permissions android.permission.INTERNET=False

默认的 Android 功能:

  • android.software.leanback=FalseFalse 表示在清单中写为 android:required="false"
  • android.hardware.touchscreen=False

跨平台权限组

有预定义的权限,分别映射到相应平台的 Info.plist*.entitlementsAndroidManifest.xml

设置跨平台权限:

flet build --permissions permission_1 permission_2...

支持的权限:

  • location
  • camera
  • microphone
  • photo_library

iOS 映射到 Info.plist 条目

  • location
    • NSLocationWhenInUseUsageDescription = This app uses location service when in use.
    • NSLocationAlwaysAndWhenInUseUsageDescription = This app uses location service.
  • camera
    • NSCameraUsageDescription = This app uses the camera to capture photos and videos.
  • microphone
    • NSMicrophoneUsageDescription = This app uses microphone to record sounds.
  • photo_library
    • NSPhotoLibraryUsageDescription = This app saves photos and videos to the photo library.

macOS 映射到授权

  • location
    • com.apple.security.personal-information.location = True
  • camera
    • com.apple.security.device.camera = True
  • microphone
    • com.apple.security.device.audio-input = True
  • photo_library
    • com.apple.security.personal-information.photos-library = True

Android 映射

  • location
    • 权限:
      • android.permission.ACCESS_FINE_LOCATION": True
      • android.permission.ACCESS_COARSE_LOCATION": True
      • android.permission.ACCESS_BACKGROUND_LOCATION": True
    • 功能:
      • android.hardware.location.network": False
      • android.hardware.location.gps": False
  • camera
    • 权限:
      • android.permission.CAMERA": True
    • 功能:
      • android.hardware.camera": False
      • android.hardware.camera.any": False
      • android.hardware.camera.front": False
      • android.hardware.camera.external": False
      • android.hardware.camera.autofocus": False
  • microphone
    • 权限:
      • android.permission.RECORD_AUDIO": True
      • android.permission.WRITE_EXTERNAL_STORAGE": True
      • android.permission.READ_EXTERNAL_STORAGE": True
  • photo_library
    • 权限:
      • android.permission.READ_MEDIA_VISUAL_USER_SELECTED": True

对应用编译和清理的控制

默认情况下,flet build 命令不再将应用的 .py 文件编译为 .pyc,这使您可以避免(推迟?)在应用中发现任何语法错误并完成打包。

您可以使用以下新选项控制编译和清理:

  • --compile-app - 编译应用的 .py 文件。
  • --compile-packages - 编译已安装包的 .py 文件。
  • --cleanup-on-compile - 在成功编译后删除不必要的文件。

为 Android 捆绑包签名

为签署 Android 构建添加了新选项:

  • --android-signing-key-store - Android 应用的上传密钥库 .jks 文件的路径。
  • --android-signing-key-store-password - Android 签名存储密码。
  • --android-signing-key-alias - Android 签名密钥别名。默认是 "upload"。
  • --android-signing-key-password - Android 签名密钥密码。

有关如何为 Android 构建配置上传密钥的更多信息,请阅读 构建和发布 Android 应用

应用的“数据”和“临时”目录

Flet 开发人员一直在询问在哪里存储应用数据,例如上传的文件、SQLite 数据库等,这些数据在应用更新期间是持久的。

此版本引入了两个在您的 Flet 应用中可用的环境变量:

  • FLET_APP_STORAGE_DATA - 用于存储在应用更新之间保留的应用数据的目录。该目录已经预先创建。
  • FLET_APP_STORAGE_TEMP - 用于临时应用文件(即缓存)的目录。该目录已经预先创建。

例如,在您的应用中可以这样读取数据文件夹路径:

import os

# 在 Web 模式下运行应用时,它为 `None`
data_dir = os.getenv("FLET_APP_STORAGE_DATA")
备注

flet run 命令会创建数据和临时目录,并将 FLET_APP_STORAGE_DATAFLET_APP_STORAGE_TEMP 设置为它们的路径。

深度链接配置

有一个新的 --deep-linking-url 选项可用于为 iOS 和 Android 构建配置深度链接。该值必须采用 <sheme>://<host> 的格式。

更快的重新构建

flet build 命令创建的临时 Flutter 应用不会一直在临时目录中重新创建,而是缓存在 build/flutter 目录中,这使得重新构建更快,改善了打包故障排除,并且不会污染临时目录。

按 ABI 拆分 APK

flet build 现在提供了内置的 --split-per-abi 选项,以按 ABI 拆分 APK。

已知的预发布问题

  • flet publish 尚未正常工作。

该版本中还会有什么

我们希望在 Flet 0.25.0 版本中包含更多内容。预计在未来几周内会有更多预发布版本。

pyproject.toml 支持

将所有 flet build 设置作为命令行选项携带是不方便且笨重的。

您将能够在 pyproject.toml[tool.flet] 部分中存储项目和构建设置。

在模拟器上运行 Flet 应用

我们将为 flet build 添加一个选项,并在真实设备或模拟器上运行打包的应用。

安装 Flutter

如果您的机器上没有合适的安装,flet build 将为您下载并配置 Flutter。

Flet v0.24.0 正式版公告

· 阅读需 8 分钟
Henri Ndonko
Flet Contributor and Maintainer

Flet 0.24.0 版本发布公告

我非常高兴地宣布 Flet 0.24.0 版本发布!它带来了一长串的错误修复、多项增强功能和新特性。

新控件

新属性

  • AudioRecordercancel_recording()
  • Videoon_completedon_track_changed
  • InputFilterunicodecase_sensitivedot_allmultiline
  • Geolocatoron_erroron_position_change
  • BarchartLineCharttooltip_border_sidetooltip_directiontooltip_fit_inside_horizontallytooltip_fit_inside_verticallytooltip_horizontal_offsettooltip_margintooltip_max_content_widthtooltip_paddingtooltip_rounded_radiustooltip_rotate_angle
  • Containerdecorationforeground_decorationignore_interactionsimage
  • PageViewdecorationforeground_decoration
  • CupertinoTextFieldenable_scribbleimageobscuring_characterpaddingscroll_paddingon_click
  • DataTableheading_row_alignment
  • TextFieldcounterdisabled_hint_contentoptions_fill_horizontally
  • ExpansionTilemin_tile_heightshow_trailing_icon
  • Markdownfit_contentimg_error_contentmd_style_sheetshrink_wrapsoft_line_breakon_selection_change
  • MenuItemButtonautofocusoverflow_axissemantic_label
  • Tabslabel_paddinglabel_text_stylepaddingsplash_border_radiusunselected_label_text_styleon_click
  • 还有很多新类(枚举、数据类、事件)……

增强功能

  • 打印事件时,事件的字符串输出更好了。
  • Image.filter_quality现在的默认值是FilterQuality.MEDIUM(之前是FilterQuality.LOW),对于缩小的图像来说,这是一个更好的默认值。
  • Geolocator控件得到了改进,通过新添加的on_position_change事件支持位置流。当定义了这个事件后,你将能够“监听”位置的变化。
  • AppBar.adaptive=True并且应用在苹果平台上运行时,AppBar.actions控件现在被包装在一个Row中,然后显示。在此之前,只显示AppBar.actions列表的第一项。
  • Markdown控件得到了显著改进。现在它可以显示 SVG 图像,并且可以进行更多的自定义。
  • 一个非常受欢迎的功能是能够为应用设置背景图像或渐变。在#3820中,我们使这个功能成为可能并且易于使用。
  • rtl(从右到左)属性已添加到更多控件(NavigationRailDestinationNavigationRailAppBarCupertinoAppBarNavigationDrawer)中,以提高对从右到左文本方向的支持。
  • 引入了--no-rich-output标志(目前仅在flet build命令中),使得可以在控制台中禁用丰富输出(主要是表情符号)。更多信息请参见#3708
  • 类型提示得到了显著改进,特别是对于事件处理程序属性。在像 PyCharm 和 VSCode 这样的现代 IDE 中,你现在可以通过将鼠标悬停在控件中的事件上轻松确定事件处理程序参数的类型。此外,当你尝试访问事件处理程序参数上不存在的属性时,IDE 会突出显示错误,确保代码更加健壮且无错误。

错误修复

以下问题已成功修复:

  • #3769:当输入无效字符时,InputFilter会清除TextField的文本内容。
  • #3770Theme.floating_action_button_theme不存在。
  • #3734:确保Dropdown.alignment被正确应用。
  • #3730:在 Windows 上打包时引发UnicodeEncodeError
  • #2160Markdown控件无法渲染 SVG 图像。
  • #2158:当找不到图像时,Markdown损坏。
  • #3679:损坏的Dismissible
  • #3670Switch.heightSwitch.width未被正确应用。
  • #3612#3566:损坏的OnScrollEvent
  • #3564:损坏的TextField.capitalization
  • #3649CupertinoPicker在某些平台上跳跃滚动。
  • #3557:Impeller 在 Mac Intel 上导致空白屏幕。
  • #3574Geolocator在 Android 设备上无法工作。
  • #3505WindowEventType不包含所有全屏事件。

感谢所有报告这些问题的人!

弃用

此版本中所有弃用的项目将在 0.27.0 版本中删除。

  • ThemeVisualDensity已弃用,并已重命名为VisualDensity
  • CupertinoButtondisabled_color已弃用,并已重命名为disabled_bgcolor,这更好地反映了其用途。
  • Markdowncode_style已弃用,现在应作为code_style_sheet.code_text_style访问。
  • Containerimage_fitimage_opacityimage_repeatimage_srcimage_src_base64已弃用,现在应从类型为DecorationImageimage访问。

重大变更和迁移

工具提示

Tooltip类不再是 Flet 控件,现在是一个简单的 Python 数据类。几乎所有控件中都可用的tooltip属性现在同时支持字符串和Tooltip对象。

以下是迁移方法:

# 之前
page.add(
ft.Tooltip(
message="This is tooltip",
content=ft.Text("Hover to see tooltip"),
padding=20,
border_radius=10,
)
)

# 之后
page.add(
ft.Text(
"Hover to see tooltip",
tooltip=ft.Tooltip(
message="This is tooltip",
padding=20,
border_radius=10,
)
)
)

TextFieldInputFilter

我们修改了InputFilter.regex_string的内部处理方式。因此,你(可能)现在需要锚定你的正则表达式模式。这仅仅意味着使用开始(^)和结束($)正则表达式锚点。

例如:r"[0-9]"现在变为r"^[0-9]$"。使用这个新字符串将按预期工作,并且只允许数字,但你可能会注意到另一个问题:文本字段的最后一个字符无法删除。要解决这个问题,你需要在正则表达式中添加一个星号(*),在这种情况下,这将简单地表示“匹配零个或多个数字(包括空字符串)”。新的正则表达式现在变为r"^[0-9]*$"

为了简化此迁移,你可以使用一个 AI 工具,使用以下简单提示:“更新以下正则表达式模式:####,确保整个字符串与模式匹配,并且允许空字符串”。

事件处理程序订阅

已删除将多个回调函数订阅到一个事件处理程序的可能性,因为这在某种程度上是有偏见的(仅在某些情况下可行,而不是在所有情况下)。

以下是一个简单的例子:

import flet as ft

def main(page: ft.Page):
def print_one(e):
print("1")
def print_two(e):
print("2")
def print_three(e):
print("3")
c = ft.Container(
bgcolor=ft.Colors.random_color(),
width=300,
height=300,
)

# 订阅回调函数
c.on_tap_down = print_one
c.on_tap_down = print_two
c.on_tap_down = print_three
page.add(c)

ft.app(main)

在上面的代码中,我们将多个回调函数订阅到Container.on_tap_down事件。在 Flet 0.24.0 版本之前,运行此代码并点击Container,你将看到所有回调函数都被调用(打印出“1”、“2”和“3”)。

从 Flet 0.24.0 版本开始,一个事件 = 一个回调函数。这意味着只有最后订阅的回调函数将被执行(打印出“3”)。

因此,如果你仍然希望最终输出与第一个输出相似,你可以简单地创建一个回调函数,该函数调用其他函数:


def main(page: ft.Page):
#....

def print_all(e):
print_one(e)
print_two(e)
print_three(e)

c = ft.Container(
bgcolor=ft.Colors.random_color(),
width=300,
height=300,
on_tap_down=print_all,
)

# 或者
c.on_tap_down = print_all

结论

如你所见,我们在这个版本中做了很多更改,和往常一样,非常欢迎你的反馈!

升级到 Flet 0.24.0,测试你的应用程序,并让我们知道你对我们添加的新功能的看法。

如果你有任何问题,请加入Flet Discord 服务器或在Flet GitHub 讨论上创建一个新线程。

快乐地使用 Flet!👾

Flet v0.23.0 发布公告

· 阅读需 5 分钟
Henri Ndonko
Flet 贡献者和维护者

我们很高兴地宣布 Flet 0.23.0 的发布。这是一个重大的版本,带来了许多新特性和错误修复。

新控件

新属性

错误处理

PEP 20 (Python 之禅):错误永远不应默默地过去。

一些开发者报告说,在某些情况下,控件可能会在没有明显错误信息的情况下视觉上崩溃。

例如,在问题 #3149 中,@base-13 提到 "在 DataTable 中,如果列数少于任意一行中的数据单元格数,则整个表格将变灰而不抛出错误"

了解这一点,我们在大多数控件中添加了更多的断言检查,以便当您提供错误的值时,会引发一个 AssertionError,带有明确的错误消息。

如果您发现某些检查仍然缺失,请指出来以便我们解决。

命令行(CLI)输出

flet build 命令的输出已经被美化。

此外,添加了一个新的选项 --show-platform-matrix,它显示一个包含构建平台矩阵的表格,该表格的标题列为“命令”(可能的构建命令)和“平台”(您应该使用相应命令的设备)。

此外,当目标平台无法在您的设备上构建时,将显示一个包含构建平台矩阵的表格,并带有一个信息性消息。

重大变化

在上述“错误处理”中,我们不得不将一些重要属性标记为必需。

以下属性现在是“必需”的(必须提供和可见)当创建它们的类的实例时:

错误修复

以下问题已成功修复:

特别感谢活跃的 Flet 社区报告了他们遇到的所有问题。我们将继续努力解决剩余的问题。

废弃

  • 所有 Page.window_*** 属性现在已废弃,已移动到 Page.window 属性,该属性的类型为 Window。 要迁移,请简单地使用 window_ 替换为 window.,如下所示:

    # 之前
    page.window_height = 200
    page.on_window_event = lambda e: print(e.type)

    # 现在
    page.window.height = 200
    page.window.on_event = lambda e: print(e.type)
  • SafeArea.minimum 已废弃,已重命名为 minimum_padding

  • MaterialState 枚举已废弃,已重命名为 ControlState

  • NavigationDestination 已废弃,已重命名为 NavigationBarDestination

此外,废弃策略已修改。在 Flet 为 pre-1.0 时,所有废弃都会在下一个 3 个版本后从 API 中删除。 所以在 v0.23.0 中(以及之前版本中)进行的上述废弃,将在 v0.26.0 中删除。

就是这样! :)

升级到 Flet 0.23.0,测试您的应用程序,并让我们知道您对新功能的看法。 如果您有任何问题,请加入 Flet Discord 服务器 或创建一个新的线程 Flet GitHub 讨论

祝您愉快地使用 Flet!