python Windows GUI 方案 flet, 基于 flutter 组件

文章目录

    在调研 python tkinter 的 Windows GUI 客户端方案时,突然看到某个公众号文章中有人评论到为何不用 flet。
    正好出差当天晚上睡得早,凌晨 3 点半就再也睡不着了,于是手机上翻看了 flet 官网上的所有文档,发现真是一个宝藏啊。

    语法简单,且基于 flutter 的组件库,颜值有保障。而且还有跨平台的潜力。

    安装 flet

    安装方法极度简单,按照官方文档,一行

    pip install flet
    

    搞定。

    Hello world

    import flet as ft
    
    
    def main(page: ft.Page):
        page.title = "长征般的出差"
        t = ft.Text(value="出差忘带大裤衩,真是失误", color="blue")
        page.controls.append(t)
        page.add(
            ft.FilledButton(text="下次一定记住", icon="add"),
            ft.FilledButton("下次也不一定", disabled=True),
        )
        page.update()
    
    
    ft.app(target=main)
    

    界面效果

    python GUI flet

    已经非常赞了,比 WinForm / WPF / tkinter 的默认按钮好看太多了。

    通过 flet module path, 找到 flet.exe

    要交付,就不得不面对打包问题。

    打包需要用到 flet.exe 命令。

    由于我是通过 Windows Store 安装的 Python 3.11, 所以我并不清楚 flet 位于哪里,也就没法添加其目录到系统 PATH 环境变量中。

    查看方法:

    > python
    Python 3.11.4 (tags/v3.11.4:d2340ef, Jun  7 2023, 05:45:37) [MSC v.1934 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>>
    >>> import flet
    >>> flet.__file__
    'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\flet\\__init__.py'
    

    查看目录:

    > cd 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\'
    > dir
    
    Mode                 LastWriteTime         Length Name
    ----                 -------------         ------ ----
    d-----        2023-07-28     17:10                Scripts
    d-----        2023-07-28     17:10                site-packages
    
    > cd .\Scripts\
    > dir
    
    Mode                 LastWriteTime         Length Name
    ----                 -------------         ------ ----
    d-----        2023-07-28     17:04                __pycache__
    -a----        2023-07-28     17:04         108461 flet.exe
    -a----        2023-07-28     17:04         108454 httpx.exe
    -a----        2023-07-28     17:10         108499 pyinstaller.exe
    -a----        2023-07-28     17:04          27255 pywin32_postinstall.py
    -a----        2023-07-28     17:04           3721 pywin32_testall.py
    

    果然找到了 flet.exe.

    修改 Windows 11 系统环境变量没有生效

    虽然我修改了系统环境变量,但是没有生效,可能是路径中有特殊符号?

    > echo %PATH%
    C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\dotnet\;D:\apps\Git\cmd;C:\Users\zhong\AppData\Local\Microsoft\WindowsApps;C:\Users\zhong\.dotnet\tools;D:\apps\Microsoft VS Code\bin
    

    简单的方式是复制一份 flet.exe 到 C:\WINDOWS

    打包

    > flet.exe pack D:\work\test\flet\main.py
    Updating Flet View version info C:\Users\zhong\AppData\Local\Temp\04d2ac14-813d-4ef9-939c-4e260286327c\flet\flet.exe
    Running PyInstaller: ['D:\\work\\test\\flet\\main.py', '--noconsole', '--noconfirm', '--onefile', '--version-file', 'C:\\Users\\zhong\\AppData\\Local\\Temp\\3f5070af-bcaf-4fe0-9eec-cbec2e856070']
    7157 INFO: PyInstaller: 5.13.0
    7157 INFO: Python: 3.11.4
    7173 INFO: Platform: Windows-10-10.0.22621-SP0
    7188 INFO: wrote C:\Users\zhong\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\Scripts\main.spec
    7219 INFO: Extending PYTHONPATH with paths
    ['D:\\work\\test\\flet']
    10097 INFO: checking Analysis
    10097 INFO: Building Analysis because Analysis-00.toc is non existent
    10097 INFO: Initializing module dependency graph...
    10112 INFO: Caching module graph hooks...
    10253 INFO: Analyzing base_library.zip ...
    17899 INFO: Loading module hook 'hook-heapq.py' from 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\PyInstaller\\hooks'...
    18259 INFO: Loading module hook 'hook-encodings.py' from 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\PyInstaller\\hooks'...
    23574 INFO: Loading module hook 'hook-pickle.py' from 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\PyInstaller\\hooks'...
    28452 INFO: Caching module dependency graph...
    28862 INFO: running Analysis Analysis-00.toc
    28893 INFO: Adding Microsoft.Windows.Common-Controls to dependent assemblies of final executable
      required by C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.1264.0_x64__qbz5n2kfra8p0\python.exe
    28893 WARNING: lib not found: api-ms-win-appmodel-runtime-l1-1-0.dll dependency of C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.1264.0_x64__qbz5n2kfra8p0\python.exe
    29472 INFO: Analyzing D:\work\test\flet\main.py
    29534 INFO: Loading module hook 'hook-flet.py' from 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\flet\\__pyinstaller'...
    30191 INFO: Loading module hook 'hook-difflib.py' from 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\PyInstaller\\hooks'...
    30894 INFO: Loading module hook 'hook-multiprocessing.util.py' from 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\PyInstaller\\hooks'...
    31380 INFO: Loading module hook 'hook-xml.py' from 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\PyInstaller\\hooks'...
    32928 INFO: Loading module hook 'hook-platform.py' from 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\PyInstaller\\hooks'...
    33977 INFO: Loading module hook 'hook-certifi.py' from 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\_pyinstaller_hooks_contrib\\hooks\\stdhooks'...
    35650 INFO: Loading module hook 'hook-anyio.py' from 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\_pyinstaller_hooks_contrib\\hooks\\stdhooks'...
    39700 INFO: Loading module hook 'hook-pygments.py' from 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\PyInstaller\\hooks'...
    46518 INFO: Loading module hook 'hook-pkg_resources.py' from 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\PyInstaller\\hooks'...
    51662 INFO: Loading module hook 'hook-sysconfig.py' from 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\PyInstaller\\hooks'...
    54553 INFO: Processing pre-safe import module hook six.moves from 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\PyInstaller\\hooks\\pre_safe_import_module\\hook-six.moves.py'.
    55100 INFO: Loading module hook 'hook-websockets.py' from 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\_pyinstaller_hooks_contrib\\hooks\\stdhooks'...
    58022 INFO: Processing module hooks...
    58787 INFO: Processing pre-safe import module hook win32com from 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\_pyinstaller_hooks_contrib\\hooks\\pre_safe_import_module\\hook-win32com.py'.
    59116 INFO: Loading module hook 'hook-win32com.py' from 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\_pyinstaller_hooks_contrib\\hooks\\stdhooks'...
    59131 INFO: Loading module hook 'hook-pythoncom.py' from 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\_pyinstaller_hooks_contrib\\hooks\\stdhooks'...
    59837 INFO: Loading module hook 'hook-pywintypes.py' from 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\_pyinstaller_hooks_contrib\\hooks\\stdhooks'...
    63260 INFO: Loading module hook 'hook-jinja2.py' from 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\_pyinstaller_hooks_contrib\\hooks\\stdhooks'...
    64629 INFO: Loading module hook 'hook-packaging.py' from 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\PyInstaller\\hooks'...
    71461 INFO: Looking for ctypes DLLs
    71539 INFO: Analyzing run-time hooks ...
    71539 INFO: Including run-time hook 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_inspect.py'
    71562 INFO: Including run-time hook 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\flet\\__pyinstaller\\rthooks\\pyi_rth_localhost_fletd.py'
    71562 INFO: Including run-time hook 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_pkgutil.py'
    71571 INFO: Including run-time hook 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_multiprocessing.py'
    71586 INFO: Including run-time hook 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_pkgres.py'
    71602 INFO: Including run-time hook 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_win32comgenpy.py'
    71602 INFO: Including run-time hook 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\_pyinstaller_hooks_contrib\\hooks\\rthooks\\pyi_rth_pywintypes.py'
    71602 INFO: Including run-time hook 'C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\_pyinstaller_hooks_contrib\\hooks\\rthooks\\pyi_rth_pythoncom.py'
    71649 INFO: Looking for dynamic libraries
    3063 INFO: Extra DLL search directories (AddDllDirectory): []
    3063 INFO: Extra DLL search directories (PATH): ['C:\\Program Files (x86)\\Common Files\\Oracle\\Java\\javapath', 'C:\\WINDOWS\\system32', 'C:\\WINDOWS', 'C:\\WINDOWS\\System32\\Wbem', 'C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\', 'C:\\WINDOWS\\System32\\OpenSSH\\', 'C:\\Program Files\\dotnet\\', 'D:\\apps\\Git\\cmd', 'C:\\Users\\zhong\\AppData\\Local\\Microsoft\\WindowsApps', 'C:\\Users\\zhong\\.dotnet\\tools', 'D:\\apps\\Microsoft VS Code\\bin']
    3517 WARNING: lib not found: pywintypes311.dll dependency of C:\Users\zhong\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\win32\win32trace.pyd
    3595 WARNING: lib not found: pywintypes311.dll dependency of C:\Users\zhong\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\Pythonwin\win32ui.pyd
    3813 WARNING: lib not found: pywintypes311.dll dependency of C:\Users\zhong\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\win32\win32api.pyd
    3985 WARNING: lib not found: pywintypes311.dll dependency of C:\Users\zhong\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\win32comext\shell\shell.pyd
    4001 WARNING: lib not found: pythoncom311.dll dependency of C:\Users\zhong\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\win32comext\shell\shell.pyd
    76636 INFO: Looking for eggs
    76652 INFO: Using Python library C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.1264.0_x64__qbz5n2kfra8p0\python311.dll
    76652 INFO: Found binding redirects:
    []
    76683 INFO: Warnings written to C:\Users\zhong\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\Scripts\build\main\warn-main.txt
    76996 INFO: Graph cross-reference written to C:\Users\zhong\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\Scripts\build\main\xref-main.html
    77246 INFO: checking PYZ
    77246 INFO: Building PYZ because PYZ-00.toc is non existent
    77246 INFO: Building PYZ (ZlibArchive) C:\Users\zhong\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\Scripts\build\main\PYZ-00.pyz
    79654 INFO: Building PYZ (ZlibArchive) C:\Users\zhong\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\Scripts\build\main\PYZ-00.pyz completed successfully.
    79764 INFO: checking PKG
    79764 INFO: Building PKG because PKG-00.toc is non existent
    79764 INFO: Building PKG (CArchive) main.pkg
    92834 INFO: Building PKG (CArchive) main.pkg completed successfully.
    92834 INFO: Bootloader C:\Users\zhong\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\PyInstaller\bootloader\Windows-64bit-intel\runw.exe
    92834 INFO: checking EXE
    92834 INFO: Building EXE because EXE-00.toc is non existent
    92834 INFO: Building EXE from EXE-00.toc
    92850 INFO: Copying bootloader EXE to C:\Users\zhong\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\Scripts\dist\main.exe.notanexecutable
    93006 INFO: Copying icon to EXE
    93022 INFO: Copying icons from ['C:\\Users\\zhong\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\PyInstaller\\bootloader\\images\\icon-windowed.ico']
    93100 INFO: Writing RT_GROUP_ICON 0 resource with 104 bytes
    93100 INFO: Writing RT_ICON 1 resource with 3752 bytes
    93100 INFO: Writing RT_ICON 2 resource with 2216 bytes
    93100 INFO: Writing RT_ICON 3 resource with 1384 bytes
    93100 INFO: Writing RT_ICON 4 resource with 38188 bytes
    93100 INFO: Writing RT_ICON 5 resource with 9640 bytes
    93100 INFO: Writing RT_ICON 6 resource with 4264 bytes
    93100 INFO: Writing RT_ICON 7 resource with 1128 bytes
    93100 INFO: Copying version information to EXE
    93194 INFO: Copying 0 resources to EXE
    93194 INFO: Embedding manifest in EXE
    93194 INFO: Updating manifest in C:\Users\zhong\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\Scripts\dist\main.exe.notanexecutable
    93256 INFO: Updating resource type 24 name 1 language 0
    93272 INFO: Appending PKG archive to EXE
    93350 INFO: Fixing EXE headers
    99745 INFO: Building EXE from EXE-00.toc completed successfully.
    Deleting temp directory: C:\Users\zhong\AppData\Local\Temp\04d2ac14-813d-4ef9-939c-4e260286327c
    

    文件大小

    2023-07-28  19:34    <DIR>          .
    2023-07-28  19:33    <DIR>          ..
    2023-07-28  19:34        31,084,804 main.exe
    

    WSL 中查看

    > ls -lah dist/
    total 30M
    drwxrwxrwx 1 zhongwei zhongwei 4.0K Jul 28 19:45 ./
    drwxrwxrwx 1 zhongwei zhongwei 4.0K Jul 28 19:44 ../
    -rwxrwxrwx 1 zhongwei zhongwei  30M Jul 28 19:45 main.exe
    

    大小倒是可以接受。

    启动速度

    打包后的 EXE,启动速度 4,5 秒。这个真是无法接受。得找方案优化一下。

    • 不打包成一个文件,多个文件发布完全可以接受
    • 不使用 flet 默认的 pyinstaller 方案
    • 尝试 pyinstaller 其他打包参数

    参考

    • https://flet.dev/docs/guides/python/packaging-desktop-app
    • https://blog.csdn.net/tqlisno1/article/details/108951702

    关于作者 🌱

    我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式