Flet 快速上手

Flet 快速上手

Flet 是什么?

Flet 是一个 UI 框架,允许你使用 Python 来构建 Web、桌面端和移动端应用。

构建第一个 Flet 应用

下面将构建我们的第一个 Flet 应用,该应用只有一个简单的计数功能。

首先我们需要执行命令 pip install flet 来安装 flet。然后我们创建一个 counter.py 文件用于实现我们的计数 app。在 counter.py 中加上如下代码:

import flet
from flet import IconButton, Page, Row, TextField, icons

def main(page: Page):
    page.title = "Flet counter example"
    page.vertical_alignment = "center"

    txt_number = TextField(value="0", text_align="right", width=100)

    def minus_click(e):
        txt_number.value = str(int(txt_number.value) - 1)
        page.update()

    def plus_click(e):
        txt_number.value = str(int(txt_number.value) + 1)
        page.update()

    page.add(
        Row(
            [
                IconButton(icons.REMOVE, on_click=minus_click),
                txt_number,
                IconButton(icons.ADD, on_click=plus_click),
            ],
            alignment="center",
        )
    )

flet.app(target=main)

接下来只需要使用命令 python counter.py 即可运行我们的第一个 flet 应用了。

Flet counter example

在实际开发中使用 flet create <project-name> 来创建一个 flet 项目,使用 flet run 来运行 flet 项目。

基本概念

Controls

用户界面在 Flet 中是由一个一个的 control 组成的,control 只能在 control 内,其中 Page 是最顶级的 control,也就是说用户看到的界面其实是一棵 control 树。下述代码就是将一个 Text control 加入到 Page 内,然后调用 update 来更新界面:

import flet as ft

def main(page: ft.Page):
    t = ft.Text(value="Hello, world!", color="green")
    page.controls.append(t)
    page.update()

ft.app(target=main)

上述代码中 Text 就是 Flet 提供的 control,我们也可以自定义 control 来灵活实现需求:

class MyButton(ft.ElevatedButton):
    def __init__(self, text):
        super().__init__()
        self.bgcolor = ft.colors.ORANGE_300
        self.color = ft.colors.GREEN_800
        self.text = text     

在自定义的 ByButton 中会继承 Flet 的 ElevatedButton control 然后修改其字体和背景色。

control 还提供了一些钩子函数:

  • build:创建 control 时调用

  • did_mount:control 被挂载后调用

  • will_unmount:移除 control 后调用

  • before_update:更新 control 前调用

Adaptive apps

Flet 框架提供了多平台自适应功能,此功能默认为关闭状态,将 page.adaptive 设置为 True 将开启自适应功能。开启自适应功能后一些 controls 在 IOS 和其它平台中显示样式会不一样。Flet 提供的自适应 control 请阅读文档:Material and Cupertino controls

除此之外我们可以自定义 control 来实现多平台适配。在自定义 control 中检查 self.page.platform 来区分程序当前运行的平台:

class AdaptiveNavigationBarDestination(ft.NavigationBarDestination):
    def __init__(self, ios_icon, android_icon, label):
        super().__init__()
        self._ios_icon = ios_icon
        self._android_icon = android_icon
        self.label = label

    def build(self):
        # we can check for platform in build method because self.page is known
        self.icon = (
            self._ios_icon
            if self.page.platform == ft.PagePlatform.IOS
            or self.page.platform == ft.PagePlatform.MACOS
            else self._android_icon
        )

Flet 提供了路由功能。Flet 提供了两种路由模式:

  • Path:普通路由,如:/post/1

  • Hash:哈希路由,如:/#/post/1

我们可以通过page.route属性来获取当前页面的路由同时也能修改此熟悉从而实现跳转路由的功能。Flet 还提供了 page.on_route_change来监听路由变化。使用 page.on_view_pop可以获取上一个页面试图。

import flet as ft

def main(page: ft.Page):
    page.add(ft.Text(f"Initial route: {page.route}"))

    def route_change(e: ft.RouteChangeEvent):
        page.add(ft.Text(f"New route: {e.route}"))

    def go_store(e):
        page.route = "/store"
        page.update()

    page.on_route_change = route_change
    page.add(ft.ElevatedButton("Go to Store", on_click=go_store))

ft.app(target=main, view=ft.AppView.WEB_BROWSER)

打包 Flet 项目

Flet 打包程序提供了两种方法

  • flet pack main.py:这是旧的打包 flet 程序命令,依赖 pyinstaller。注意:这种方法方法打包优点是较为简单,缺点是打包出的程序性能较差(简单 demo 打包后打开时间要七秒左右,使用 flet build 打包仅一秒多即可打开)

  • flet build macos:这是新打包命令,依赖 Flutter。

Flet pack demo

下述示例是基于 MacOS 14 m2 芯片构建

使用 flet pack 命令打包程序前需要先使用 pip install pyinstaller命令来安装 pyinstaller 依赖。然后执行 flet pack main.py 即可打包程序。 命令详情参考文档:packaging-desktop-app

Flet build demo

下述示例是基于 MacOS 14 m2 芯片构建

环境准备

  • 网络环境:打包构建过程中会使用到一些外网依赖故需要提前配置网络代理,配置方法可参考命令export http_proxy=http://127.0.0.1:1087;export https_proxy=http://127.0.0.1:1087对应端口为本机实际代理端口。

  • Flutter 环境:由于 Flet 打包构建实际是使用 Fletter,故我们需要配置 Flutter 环境。

    • 下载安装 Flutter SDK:install-the-flutter-sdk 打开链接后选择 Download and install 中 arm 版本压缩包下载解压。然后如下环境变量:

      • export PUB_HOSTED_URL=https://pub.flutter-io.cn

      • export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn

      • export PATH="{flutter sdk 安装目录}/bin:$PATH"

    • 打开 AppStore 商店安装 Xcode,用于编译 Swift,安装过程可能会让你升级操作系统。

    • 安装 CocoaPods 用于编译 Flutter,CocoaPods 其作用为管理依赖。

    • how-it-workshttps://flet.dev/docs/publish#how-it-works

打包

使用名flet build <target_platform>即可打包 Flet 项目,具体打包命令参考文档:how-it-works

Github Action demo

由于 flet pack 打包性能较差,故 github action 打包构建将使用 flet build 方式进行。

name: Test build

on:
  release:
    types: [ created ]

  # Allows you to run this workflow manually from the Actions tab of the repository
  workflow_dispatch:

# flet build macos --verbose --build-number=1 --build-version=1.0.0
env:
  PYTHON_VERSION: 3.11.9
  FLUTTER_VERSION: 3.24.0

jobs:
  build-macos:
    strategy:
      matrix:
        os: [macos-14]  # 定义多个 macOS 版本,macos-14是m1芯片即arm64
    runs-on: macos-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v4

    - name: Setup Python ${{ env.PYTHON_VERSION }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ env.PYTHON_VERSION }}

    - name: Install Python Dependencies
      run: |
        python -m pip install --upgrade pip
        pip install -r requirements.txt

    - name: Setup Flutter ${{ env.FLUTTER_VERSION }}
      uses: subosito/flutter-action@v2
      with:
        flutter-version: ${{ env.FLUTTER_VERSION }}

    - name: Flet Build macOS
      run: |
        flutter config --no-analytics
        flet build macos --verbose

    - name: Package .app folder
      run: |
         cd build/macos
         tar -czf test.tar.gz test.app
         cd ../
         cd ../
         mkdir dist
         cp build/macos/test.tar.gz dist/test.tar.gz

    - name: Upload Release Asset
      id: upload-release-asset
      uses: actions/upload-release-asset@v1
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      with:
        upload_url: ${{ github.event.release.upload_url }}
        asset_path: ./dist/test.tar.gz
        asset_name: test-${{ matrix.os }}.tar.gz
        asset_content_type: application/octet-stream

参考资料

  1. https://flet.dev/docs

  2. https://docs.flutter.dev/get-started/install/macos/desktop

  3. https://cocoapods.org

posted @ 2024-09-29 10:10  TKG  阅读(3235)  评论(0)    收藏  举报