跳到主要内容

Flet版本控制和预发布

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

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

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

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

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

安装预发布版本

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

pip install flet --pre
信息

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

Flet版本控制

Flet将切换到语义化版本控制,版本号格式为MAJOR.MINOR.PATCH

  1. 当存在“不兼容的API更改”时,MAJOR将递增。目前是0,当我们认为Flet API足够稳定时,我们将其更改为1
  2. 当以向后兼容的方式添加新功能时,MINOR将递增。
  3. 当进行向后兼容的错误修复时,PATCH将递增。

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

Flet的预发布版本将采用MAJOR.{LAST_MINOR + 1}.0.dev{BUILD}的格式,其中LAST_MINOR是上一个发布的MINOR版本,{BUILD}是由CI设置的构建号。例如,如果最后发布的版本是0.1.65,那么预发布版本将具有版本号0.2.0.dev{BUILD}。在0.2.0发布之后的预发布版本将被标记为0.3.0.dev{BUILD}

ResponsiveRow 和移动端控件

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

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

ResponsiveRow 控件

ResponsiveRow 借鉴了 Bootstrap 网页框架的网格布局思想。

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

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

import flet as ft

ft.ResponsiveRow([
ft.Column(col=6, controls=ft.Text("列 1")),
ft.Column(col=6, controls=ft.Text("列 2"))
])

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("列 1")),
ft.Column(col={"sm": 6}, controls=ft.Text("列 2"))
])

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

import flet as ft

def main(page: ft.Page):
def page_resize(e):
pw.value = f"{page.width} px"
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("列 1"),
padding=5,
bgcolor=ft.colors.YELLOW,
col={"sm": 6, "md": 4, "xl": 2},
),
ft.Container(
ft.Text("列 2"),
padding=5,
bgcolor=ft.colors.GREEN,
col={"sm": 6, "md": 4, "xl": 2},
),
ft.Container(
ft.Text("列 3"),
padding=5,
bgcolor=ft.colors.BLUE,
col={"sm": 6, "md": 4, "xl": 2},
),
ft.Container(
ft.Text("列 4"),
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),将认证集成到您的应用程序中,并告诉我们您的想法!

手势检测器

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

我们刚刚发布了支持手势处理的 Flet 0.1.62版本!

这里有一个新的控件 - GestureDetector,它可以处理各种手势:左(主要)和右(次要)鼠标(指针)按钮的单击和双击手势,垂直、水平和双向拖动,缩放(收缩和扩张)手势以及悬停事件。现在,通过将其包装到 GestureDetector 中,您可以使任何 Flet 控件具有"可点击"和"可拖动"的功能!

下面是一个简单的示例,演示了一个应用程序,允许你在 Stack 中拖动容器:

import flet as ft

def main(page: ft.Page):
def on_pan_update(e: ft.DragUpdateEvent):
e.control.top = max(0, e.control.top + e.delta_y)
e.control.left = max(0, e.control.left + e.delta_x)
e.control.update()

gd = ft.GestureDetector(
mouse_cursor=ft.MouseCursor.MOVE,
on_vertical_drag_update=on_pan_update,
left=100,
top=100,
content=ft.Container(bgcolor=ft.colors.BLUE, width=50, height=50, border_radius=5),
)

page.add(ft.Stack([gd], expand=True))

ft.app(target=main)

手势检测器是 Flet 的又一个伟大的补充,它使您能够构建仅受您想象力限制的应用程序。本月晚些时候即将到来的 2D 绘图功能将完善这一功能集合!

这个版本不仅涉及手势,还包含了一些"稳定性"修复。我们修复了一些错误,并添加了一些其他小功能,您可以在这里查看。

升级到最新版本的 Flet 模块(pip install flet --upgrade),将身份验证集成到您的应用程序中,并让我们知道您的想法 (链接)

Enjoy!

用户认证

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

Flet 现在支持用户认证了!🎉

现在,您可以在 Flet 应用中实现用户认证("Login with X"按钮),使用第三方身份提供者,如 GitHub、Google、Azure、Auth0、LinkedIn 等:

这个发布不仅仅是关于认证,还新增了很多相关功能和小的改进:

认证

Flet 的认证特性:

  • 支持 Flet 桌面应用、Web 应用和移动应用。
  • 在一个应用中使用多个认证提供者。
  • 内置的 OAuth 认证提供者,自动获取用户详细信息:
    • GitHub
    • Azure
    • Google
    • Auth0
  • 可选的群组获取。
  • 自动令牌刷新。
  • 使用保存的令牌登录("Remember me")。
  • 自定义 OAuth 提供者。

下面是如何在您的 Flet 应用中添加 "Login with GitHub" 按钮的简单示例:

import os

import flet as ft
from flet.auth.providers.github_oauth_provider import GitHubOAuthProvider

def main(page: ft.Page):

provider = GitHubOAuthProvider(
client_id=os.getenv("GITHUB_CLIENT_ID"),
client_secret=os.getenv("GITHUB_CLIENT_SECRET"),
redirect_url="http://localhost:8550/api/oauth/redirect",
)

def login_click(e):
page.login(provider)

def on_login(e):
print("Access token:", page.auth.token.access_token)
print("User ID:", page.auth.user.id)

page.on_login = on_login
page.add(ft.ElevatedButton("Login with GitHub", on_click=login_click))

ft.app(target=main, port=8550, view=ft.AppView.WEB_BROWSER)
备注

在运行应用之前,请在命令行中设置秘密环境变量:

$ export GITHUB_CLIENT_ID="<client_id>"
$ export GITHUB_CLIENT_SECRET="<client_secret>"

阅读认证指南了解更多信息和示例.

客户端存储

Flet 提供了客户端存储 API,用于在客户端上使用持久化存储存储键值数据。Flet 使用 shared_preferences Flutter 包进行实现。

将数据写入存储:

page.client_storage.set("key", "value")

读取数据:

value = page.client_storage.get("key")

阅读客户端存储指南了解更多信息和示例.

会话存储

Flet 引入了在用户会话中存储键值数据的 API。

将数据写入会话:

page.session.set("key", "value")

读取数据:

value = page.session.get("key")

阅读会话存储指南了解更多信息和示例

加密 API

此版本中,Flet 引入了使用对称算法(加密和解密使用相同的密钥)加密和解密敏感文本数据的实用方法。它使用了来自 cryptography 包的 Fernet 实现,其中使用了 AES 128 与一些额外的加固措施,再加上 PBKDF2 从用户的口令派生加密密钥。

加密数据:

from flet.security import encrypt, decrypt
secret_key = "S3CreT!"
plain_text = "This is a secret message!"
encrypted_data = encrypt(plain_text, secret_key)

解密数据:

from flet.security import encrypt, decrypt
secret_key = "S3CreT!"
plain_text = decrypt(encrypted_data, secret_key)
print(plain_text)

继续阅读获取更多信息和示例

其他改进

import flet as ft
def main(page: ft.Page):
page.window_bgcolor = ft.colors.TRANSPARENT
page.bgcolor = ft.colors.TRANSPARENT
page.window_title_bar_hidden = True
page.window_frameless = True
page.window_left = 400
page.window_top = 400
page.add(ft.ElevatedButton("我是浮动按钮!"))
ft.app(target=main)
  • page.get_clipboard()
  • page.launch_url() - 通过额外的参数更好地控制打开链接:
    • web_window_name - 打开链接的窗口标签/名称:_self - 当前选项卡,_blank - 新选项卡,或者<你的名称> - 指定名称的选项卡。
    • web_popup_window - 设置为True以在浏览器弹出窗口中显示链接。默认为False
    • window_width - 可选,弹出窗口的宽度。
    • window_height - 可选,弹出窗口的高度。
  • page.window_to_front()
  • page.close_in_app_web_view()

升级到最新版本的Flet模块(pip install flet --upgrade),在你的应用中集成身份验证,并且请告诉我们你的想法!