跳到主要内容

使用自定义图标打包桌面应用程序

· 阅读需 2 分钟
Feodor Fitsner
Flet 创始人兼开发者

新年快乐!Flet 项目 在 GitHub 上达到了 ⭐️ 3.3K 星 ⭐️,这非常令人兴奋和鼓舞!感谢大家的支持!

我们从发布 Flet 0.3.2 开始新的一年,这次更新带来了一个期待已久的功能:创建具有自定义图标的独立桌面软件包!

flet 命令一直用于运行带有热重载的 Flet 程序,但我们最近重新设计了 Flet CLI,以支持多种操作。

新增的 flet pack 命令封装了 PyInstaller API,将您的 Flet Python 应用程序打包成独立的 Windows 可执行文件或 macOS 应用程序包,用户无需安装 Python 即可运行。

命令的 --icon 参数不仅改变了可执行文件的图标,还改变了 Flet 的应用程序窗口图标以及在 macOS Dock、Windows 任务栏、macOS "关于" 对话框、任务管理器和活动监视器中显示的图标:

还可以更改包名称、版本和版权信息:

更新的指南中查找所有可用的桌面应用程序打包选项。

将 Flet 模块升级到最新版本 (pip install flet --upgrade),试一试 flet pack 命令,并告诉我们您的想法!

Flet 移动端更新

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

本文是几个月前发布的Flet 移动端战略的延续。

我们最初在移动设备上运行 Flet 的方法是服务器驱动的 UI(SDUI)。尽管 SDUI 有其自身的优点(比如绕过应用商店进行应用更新),但它并不适用于所有情况,需要 Web 服务器来托管应用程序的 Python 部分,并且由此增加了响应延迟,这对于需要几乎即时 UI 响应的用户操作(如绘图应用程序)并不理想。

我一直在思考如何将 Python 运行时嵌入到 Flutter iOS 或 Android 应用程序中以运行用户的 Python 程序。毫无疑问,从技术上讲是可行的,因为 Kivy 和 BeeWare 项目已经实现了这一点。

当前的 Flet 架构

当前 Flet 桌面应用程序的架构如下图所示:

在桌面上运行 Flet 程序涉及到三个应用程序(进程)协同工作:

  • Python 运行时 (python3) - 运行您的 Python 脚本的 Python 解释器。这是您从命令行启动的内容。Python 启动 Fletd 服务器并通过 WebSockets 连接到它。
  • Fletd 服务器 (fletd) - 使用 Go 编写的 Flet Web 服务器,监听一个 TCP 端口。Fletd 保存所有用户会话的状态(对于桌面应用程序只有一个会话),并在 Python 程序和 Flet 客户端之间分发页面更新和用户生成的事件。
  • Flet 客户端 (flet) - 使用 Flutter 编写的桌面应用程序,在本地操作系统窗口中显示 UI。Flet 客户端通过 WebSockets 连接到 Fletd 服务器。

上述架构对于 Flet Web 应用程序效果良好,因为 Web 服务器是必要的一部分,但对于桌面应用程序来说似乎是多余的:

  • 如果所有三个进程在同一台计算机上运行,WebSockets 可以用消息传递队列或命名管道替代,减少开销。
  • 对于只有一个用户会话且 UI 状态永久存储在 Flet 桌面客户端中且从不“重新加载”的桌面应用程序来说,Fletd 服务器没有多大意义。

新的 Flet 桌面架构

通过将 Fletd 替换为用 Python 编写的“存根”,并通过 sockets(Windows)和 named pipes(macOS 和 Linux)与 Flet 桌面客户端通信,可以简化 Flet 桌面应用程序的架构:

Flet 移动架构

移动应用程序在非常严格的环境中运行,有许多限制。例如,在 iOS 上,应用程序无法生成新进程。换句话说,Flet Flutter 应用程序不能简单地启动“python.exe”并将您的脚本作为参数传递。

幸运的是,Python 可以被嵌入到另一个应用程序作为 C 库,并且 Dart(Flutter 应用程序编写的语言)允许通过FFI(外部函数接口)调用 C 库。

此外,尽管 Android 允许动态链接库的加载,但 iOS 要求所有库都静态链接到应用程序可执行文件中。这篇文章更详细地介绍了 Dart FFI,如果您感兴趣的话。

Flet 移动架构可能如下所示:

Python 运行时将与 Flutter 客户端应用程序静态或动态链接,并通过 FFI 和/或具名管道进行调用。

尽管在移动设备上运行 Python 存在一些限制。最重要的限制之一是要求使用适用于移动设备 ARM64 架构的“纯” Python 模块或使用专门为移动设备编译的具有本机代码的模块。

异步支持

Asyncio 是 Python 3 的一部分,我们开始看到越来越多的库开始适应 async/await 编程模型,这对于 I/O 绑定和 UI 逻辑更有效。

目前,Flet在新线程中生成所有UI事件处理程序,而且随处可见threading.sleep()调用阻塞线程,仅仅是为了进行一些UI动画。所有这些看起来都很费资源。

使用异步库的异步代码 是可能的,但看起来很别扭且效率低下,因为它让 CPU 忙于等待异步方法完成。因此,我们希望 Flet 应用程序能够对异步代码提供一流支持。

异步/等待模型是在单个线程中切换任务的状态机。通过采用异步方式,Flet 将能够利用处理套接字服务器,并使用异步WebSockets 库库。它将能够在单个 Flet 应用程序中同时使用同步和异步事件处理程序,而无需任何妥协或黑客手段。

更令人兴奋的是,异步 Flet 将能够完全在Pyodide内运行,Pyodide 是基于 WebAssembly(WASM)的 Python 发行版。WebAssembly 尚无多线程支持,因此在单个线程中运行是必须的。想象一下,具有真正离线 Flet PWA 的 Flet Web 应用程序,它不需要 Web 服务器来运行 Python 代码!

开发计划

我们将在几个迭代中压缩上面的范围:

  1. 支持异步API,并使用异步WebSockets库。与Go中的相同Fletd一起工作。
  2. 使用Python的Fletd服务器("存根")与桌面应用程序一起使用。
  3. 将Python与Fletd“存根”和用户程序嵌入iOS中。
  4. 将Python嵌入Android中。
  5. 为iOS和Android打包移动应用程序。
寻求帮助

🙏 我正在寻求社区在开发 Flutter 和 Python 在 iOS 和 Android 之间的 C/C++/本机代码集成方面的帮助。这可以是免费帮助或有偿工作 - 如果您有兴趣,请告诉我!

请访问 Discord 讨论该计划,提供帮助,提出问题!

Flet版本控制与预发布

· 阅读需 3 分钟
费奥多·菲茨纳 (Feodor Fitsner)
Flet 创始人和开发者

Flet是一个快速发展的框架,每隔一天都会提交新功能和错误修复。

每个版本发布一个拉取请求的开发模型对项目来说效果不好,因为用户需要等待数周才能获得新版本,而且从开发角度来看,发布大型的“英勇”版本需要耗费很多精力 🫠。

从现在开始,我们将把发布拆分为多个拉取请求,每个拉取请求一个功能/错误修复。

每个合并到main分支的拉取请求将会发布一个预发布(开发中的版本)包到pypi.org,版本格式为X.Y.Z.devN

安装预发布版本

要安装Flet的预发布版本,请使用以下命令:

pip install flet --pre
信息

我们建议将预发布版本构建安装到虚拟环境中。

Flet版本控制

Flet将切换到语义化版本,版本号为 主版本.次版本.修订版本

  1. 当有“不兼容的API更改”时,将增加 主版本。现在它是 0,我们预计当Flet API足够稳定时将其设为 1
  2. 当以向后兼容的方式添加新功能时,将增加 次版本
  3. 当进行向后兼容的错误修复时,将增加 修订版本

根据这个规则,即将发布的Flet版本将是 0.2.0。该版本的错误修复将标记为 0.2.10.2.2 等。该版本之后的发布将是 0.3.0,以此类推。

Flet预发布版本的格式将为 主版本.{上一次次版本 + 1}.0.dev{构建},其中 上一次次版本 是上一个发布的 次版本{构建} 是由CI设置的构建号。例如,如果上次发布的版本是 0.1.65,预发布版本将具有版本 0.2.0.dev{构建}。发布 0.2.0 之后的预发布版本将标记为 0.3.0.dev{构建}

ResponsiveRow 和移动端控件

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

我们刚刚发布了 Flet 0.1.65,新增了一系列移动端优化控件,修复了一些错误,并引入了一个新的布局控件 - ResponsiveRow

ResponsiveRow 控件

ResponsiveRow 控件借鉴了 Bootstrap web 框架中的网格布局思想。

ResponsiveRow 允许将子控件对齐到虚拟列中。默认情况下,虚拟网格有 12 列,但可以通过 ResponsiveRow.columns 属性进行自定义。

类似于 expand 属性,现在每个控件都有一个 col 属性,用于指定控件应跨越多少列。例如,要创建一个包含两列,每列跨越 6 个虚拟列的布局:

import flet as ft

ft.ResponsiveRow([
ft.Column(col=6, controls=ft.Text("第一列")),
ft.Column(col=6, controls=ft.Text("第二列"))
])

ResponsiveRow 是"响应式"的,因为它可以根据屏幕(页面、窗口)大小的变化调整其子项的大小。上面示例中的 col 属性是一个常数,这意味着子项将在任何屏幕大小下跨越 6 列。

如果 ResponsiveRow 的子项未指定 col 属性,则该子项将跨越最大数量的列。

col 可以配置为在特定的"断点"上具有不同的值。断点是命名的维度范围:

断点尺寸
xs<576px
sm≥576px
md≥768px
lg≥992px
xl≥1200px
xxl≥1400px

例如,以下示例在移动设备上将内容折叠为单列,并在较大屏幕上占据两列:

import flet as ft

ft.ResponsiveRow([
ft.Column(col={"sm": 6}, controls=ft.Text("第一列")),
ft.Column(col={"sm": 6}, controls=ft.Text("第二列"))
])

下面是一个更复杂的响应式布局示例:

import flet as ft

def main(page: ft.Page):
def page_resize(e):
pw.value = f"{page.width} 像素"
pw.update()

page.on_resize = page_resize

pw = ft.Text(bottom=50, right=50, style="displaySmall")
page.overlay.append(pw)
page.add(
ft.ResponsiveRow(
[
ft.Container(
ft.Text("第一列"),
padding=5,
bgcolor=ft.colors.YELLOW,
col={"sm": 6, "md": 4, "xl": 2},
),
ft.Container(
ft.Text("第二列"),
padding=5,
bgcolor=ft.colors.GREEN,
col={"sm": 6, "md": 4, "xl": 2},
),
ft.Container(
ft.Text("第三列"),
padding=5,
bgcolor=ft.colors.BLUE,
col={"sm": 6, "md": 4, "xl": 2},
),
ft.Container(
ft.Text("第四列"),
padding=5,
bgcolor=ft.colors.PINK_300,
col={"sm": 6, "md": 4, "xl": 2},
),
],
),
ft.ResponsiveRow(
[
ft.TextField(label="文本框 1", col={"md": 4}),
ft.TextField(label="文本框 2", col={"md": 4}),
ft.TextField(label="文本框 3", col={"md": 4}),
],
run_spacing={"xs": 10},
),
)
page_resize(None)

ft.app(target=main)

ResponsiveRow 文档, 示例

其他新控件

此版本添加了 Flet 社区请求的新的可视化和非可视化控件,也是构建即将推出的 Flet Studio 的用户界面所需的控件。

BottomSheet

显示一个模态 Material Design 底部表单:

BottomSheet 文档, 示例

底部导航栏,提供了一种固定且方便的方式来在应用程序中切换主要目的地:

NavigationBar 文档, 示例

Tooltip

一个工具提示控件:

Tooltip 文档, 示例

HapticFeedback

允许访问设备上的触觉反馈(点击和振动)接口。

HapticFeedback 文档

ShakeDetector

用于检测手机晃动的控件。基于shake小部件。

ShakeDetector 文档

其他改进

Markdown 代码语法高亮

示例代码

可变字体支持

Flutter 终于支持了 可变字体,我们也将其引入到了 Flet 中!

示例代码

升级 Flet 模块到最新版本(pip install flet --upgrade),并告诉我们你的想法!

享受!

Matplotlib 和 Plotly 图表

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

我们非常高兴地介绍 Flet 0.1.63 中的 Matplotlib 和 Plotly 图表控件!

MatplotlibPlotly是最受认可的Python图表库,具有丰富的功能。它们与其他科学Python库(如Numpy或Pandas)非常兼容。

毫无疑问,要想将它们的功能作为纯粹的Flutter小部件复制是几乎不可能的。幸运的是,Matplotlib和Plotly都可以将图表导出为各种格式,例如SVG。而Flet可以显示SVG图像,这给出了一个完美的组合 - Flet用于Matplotlib和Plotly的图表控件!

这个解决方案的效果非常好,几乎可以显示MatplotlibPlotly示例库中的任何示例 - 只有您的想象力是限制!

绘制一个简单的条形图

一个漂亮的带图例的散点图

或一些多图的等高线图

查看 Matplotlib 和 Plotly 图表控件的文档:

探索 Flet 图表示例

通过示例学习Python库:

在未来的版本中,我们可能会通过实现自定义 后端 为 Matplotlib 图表添加一个交互式 "工具栏"。或者也许这是 Flet 用户的一个很好的练习?😉

此外,当Flet支持其他语言时,我们需要重新审视图表功能,使其与语言无关,因为当前的图表实现依赖于Python库。

将Flet模块升级到最新版本(pip install flet --upgrade),将认证集成到您的应用程序中,并告诉我们您的想法!

尽情享受!