【易上手快捷开发新框架技术】用Flet从零开始分步骤循序渐进编程实现购物清单助手手机应用app示例掰烂嚼碎深度讲解源代码IDE运行和调试通过截图为证

传奇开心果编程实例微博文

  • 序言
    • 首先,明确任务,任务驱动:
    • 其次,开发工具选型考虑:
    • 第三,编程思路和应用结构设计:
  • 第一步:从零开始搭建移动应用雏形框架
  • 第二步:设置窗口大小为手机屏尺寸
  • 第三步:添加手机应用特有的标题栏Appbar
  • 第四步:给标题栏添加关闭按钮并且实现功能逻辑
  • 第五步:去除窗口顶部桌面程序才有的最大化最小化关闭按钮和logo以及标题
  • 第六步:添加页面安全区组件SafeArea
  • 第七步:修改导航栏按钮名称和三个页面显示文字内容
  • 第八步:关于页面添加作者文字信息
  • 第九步:给关于页面添加图片
  • 第十步:给关于页面内容进一步修改样式
  • 第十一步:给appbar添加增加删除和保存按钮
  • 第十二步:设置标题栏appbar的标题文字样式
  • 第十三步:给主页面添加输入框和列表视图组件
  • 第十四步:每个条目前面都有一个复选框
  • 第十五步:实现勾选商品删除功能
  • 第十六步:给清单页添加数据表组件DataTable
  • 第十七步:更新页面函数居中显示页面内容
  • 第十八步:AppBar 样式修改美化
  • 第十九步: 窗口大小和无边框设置使用新的属性和AppBar 标题布局优化
  • 第二十步:清单页布局优化
  • 第二十一步:设置列表视图的高度设置滚动条根据内容自动开启
  • 第二十二步、优化设置:主页列表视图高度和清单页数据表组件高度
  • 二十三、使用json文件永久存储数据完整示例源代码
  • 第二十四、整体编程思路和结构
      • 1. 数据模型
      • 2. 数据的读写
      • 3. 界面设计
      • 4. 主函数 `main`
      • 5. 功能实现
      • 6. 启动应用
      • 总结

序言

首先,明确任务,任务驱动:

任务就是开发一款购物清单助手机应用app,帮助用户在手机上高效管理购物清单。

其次,开发工具选型考虑:

  1. 这款购物清单助手应用选择使用 Flet 库全平台、易上手、快捷开发新框架技术开发,目的是体验易上手快捷开发,高效率完成任务。

  2. Flet 库基于flutter,Flet UI 是使用 Flutter 构建的,因此你的应用程序看起来很专业,并且可以交付到任何平台。Flet继承了它专业性强的特点,继承了美观漂亮的外观、优雅的设计和妖娆的动画。ui界面很漂亮,花姿招展。组件多达一百多个,而且风格多样,又很专业,天赋好。

  3. Flet可以借力 flutter强大技术和生态支撑开发,快速解决开发中遇到的问题。

第三,编程思路和应用结构设计:

程序从 JSON 文件读取商品数据,提供输入框和列表视图,用户可添加、删除和保存选购商品信息。main 函数设置应用界面,导航栏包含“主页”和“清单”和“关于”三个选项。标题栏appbar按钮主要功能包括:添加商品、删除选中商品和保存商品清单记录。整体设计注重用户体验和可扩展性,旨在提高购物清单管理的效率。

第一步:从零开始搭建移动应用雏形框架

1.编程思路
创建三个页面,在窗口界面底部添加手机应用特有的底部导航栏组件NavigationBar,实现导航栏功能逻辑,点击导航栏按钮能切换页面。

2.示例代码

import flet as ft

def main(page: ft.Page):
    # 页面标题
    page.title = "NavigationBar Example"

    # 初始化内容
    content = ft.Text("Body!")

    # 更新页面内容的函数
    def navigate(e):
        if page.navigation_bar.selected_index == 0:
            content.value = "Explore Page Content!"
        elif page.navigation_bar.selected_index == 1:
            content.value = "Commute Page Content!"
        else:
            content.value = "Favorites Page Content!"

        page.update()

    # 设置导航栏
    page.navigation_bar = ft.NavigationBar(
        destinations=[
            ft.NavigationBarDestination(
                icon=ft.icons.EXPLORE, 
                selected_icon=ft.icons.EXPLORE_ROUNDED, 
                label="Explore"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.COMMUTE, 
                selected_icon=ft.icons.COMMUTE_ROUNDED, 
                label="Commute"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.BOOKMARK_BORDER, 
                selected_icon=ft.icons.BOOKMARK, 
                label="Favorites"
            ),
        ],
        on_change=navigate
    )

    # 添加内容到页面
    page.add(content)

    # 初始化导航栏
    page.navigation_bar.selected_index = 0
    navigate(None)

# 运行应用
ft.app(target=main)

3. 解释说明
此Python示例使用了flet库来创建一个带有底部导航栏有三个页面的应用雏形框架。以下是该代码的关键部分和功能解释:

页面初始化:

设置页面标题为“NavigationBar Example”。
创建一个文本控件content作为页面的主要内容。
导航事件处理:

定义了一个navigate函数,当导航栏的选择项发生变化时被调用。
根据当前选中的导航栏索引值更新content的值,以显示不同的页面内容。
调用page.update()来刷新页面,使更改生效。

配置导航栏:

使用ft.NavigationBar创建了一个包含三个目的地的导航栏。
每个目的地都有图标、选中状态下的图标以及标签。
设置导航栏的on_change属性为navigate函数,以便在选择项改变时触发导航逻辑。

页面布局:

将content添加到页面上。
初始化导航栏的第一个选项为选中状态,并调用navigate函数来设置初始内容。

运行应用:

使用ft.app(target=main)启动Flet应用程序,并将main函数作为目标函数。
通过这个例子,用户可以通过点击底部导航栏的不同选项来切换页面的内容。

4. 运行效果,截图为证
在这里插入图片描述

第二步:设置窗口大小为手机屏尺寸

1.编程思路
移动应用是手机使用的,所以要实现窗口手机屏大小。

2.示例代码

import flet as ft

def main(page: ft.Page):
    # 页面标题
    page.title = "NavigationBar Example"
    
    # 设置窗口大小
    page.window_width = 400
    page.window_height = 600

    # 初始化内容
    content = ft.Text("Body!")

    # 更新页面内容的函数
    def navigate(e):
        if page.navigation_bar.selected_index == 0:
            content.value = "Explore Page Content!"
        elif page.navigation_bar.selected_index == 1:
            content.value = "Commute Page Content!"
        else:
            content.value = "Favorites Page Content!"

        page.update()

    # 设置导航栏
    page.navigation_bar = ft.NavigationBar(
        destinations=[
            ft.NavigationBarDestination(
                icon=ft.icons.EXPLORE, 
                selected_icon=ft.icons.EXPLORE_ROUNDED, 
                label="Explore"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.COMMUTE, 
                selected_icon=ft.icons.COMMUTE_ROUNDED, 
                label="Commute"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.BOOKMARK_BORDER, 
                selected_icon=ft.icons.BOOKMARK, 
                label="Favorites"
            ),
        ],
        on_change=navigate
    )

    # 添加内容到页面
    page.add(content)

    # 初始化导航栏
    page.navigation_bar.selected_index = 0
    navigate(None)

# 启动应用
ft.app(target=main)

3. 解释说明

设置窗口宽度为400像素,高度为600像素。

# 设置窗口大小
 page.window_width = 400
 page.window_height = 600

代码放在页面标题设置代码下面,和它一起完成窗口初始化。

** 4. 运行效果,截图为证 **
在这里插入图片描述

第三步:添加手机应用特有的标题栏Appbar

1.编程思路

手机移动应用都有标题栏Appbar,所以接下来我们添加标题栏并且实现样式定制

2.示例代码


import flet as ft

def main(page: ft.Page):
   
    
    # 设置窗口大小
    page.window_width = 400
    page.window_height = 600

    # 初始化内容
    content = ft.Text("Body!")

    # 更新页面内容的函数
    def navigate(e):
        if page.navigation_bar.selected_index == 0:
            content.value = "Explore Page Content!"
        elif page.navigation_bar.selected_index == 1:
            content.value = "Commute Page Content!"
        else:
            content.value = "Favorites Page Content!"

        page.update()

    # 设置导航栏
    page.navigation_bar = ft.NavigationBar(
        destinations=[
            ft.NavigationBarDestination(
                icon=ft.icons.EXPLORE, 
                selected_icon=ft.icons.EXPLORE_ROUNDED, 
                label="Explore"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.COMMUTE, 
                selected_icon=ft.icons.COMMUTE_ROUNDED, 
                label="Commute"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.BOOKMARK_BORDER, 
                selected_icon=ft.icons.BOOKMARK, 
                label="Favorites"
            ),
        ],
        on_change=navigate
    )

    # 设置 AppBar
    page.appbar = ft.AppBar(
        title=ft.Text("App Title"),
        center_title=True,
        bgcolor=ft.colors.SURFACE_VARIANT,
        actions=[
            ft.IconButton(ft.icons.INFO_OUTLINED),
            ft.IconButton(ft.icons.SETTINGS),
        ],
    )

    # 添加内容到页面
    page.add(content)

    # 初始化导航栏
    page.navigation_bar.selected_index = 0
    navigate(None)

# 启动应用
ft.app(target=main)

3. 解释说明

设置 AppBar

使用ft.AppBar创建了一个顶部标题栏。
设置标题栏的标题为“App Title”,并居中显示。
设置背景颜色为ft.colors.SURFACE_VARIANT。
添加两个操作按钮:信息按钮(ft.IconButton(ft.icons.INFO_OUTLINED))和设置按钮(ft.IconButton(ft.icons.SETTINGS))。

页面布局

将content添加到页面上。
初始化导航栏的第一个选项为选中状态,并调用navigate函数来设置初始内容。

**4. 运行效果,截图为证 **
在这里插入图片描述

第四步:给标题栏添加关闭按钮并且实现功能逻辑

1.编程思路

给标题栏添加关闭按钮并且实现功能,原因是为了去除窗口顶部桌面程序才有的最大化最小化关闭按钮和logo以及标题手机应用仍然能够依靠手机关闭应用。为了去除窗口顶部桌面程序才有的最大化最小化关闭按钮和logo以及标题做准备。

2.示例代码


import flet as ft

def main(page: ft.Page):
    # 设置窗口大小
    page.window_width = 400
    page.window_height = 600
    
    # 初始化内容
    content = ft.Text("Body!")

    # 更新页面内容的函数
    def navigate(e):
        if page.navigation_bar.selected_index == 0:
            content.value = "Explore Page Content!"
        elif page.navigation_bar.selected_index == 1:
            content.value = "Commute Page Content!"
        else:
            content.value = "Favorites Page Content!"

        page.update()

    # 设置导航栏
    page.navigation_bar = ft.NavigationBar(
        destinations=[
            ft.NavigationBarDestination(
                icon=ft.icons.EXPLORE, 
                selected_icon=ft.icons.EXPLORE_ROUNDED, 
                label="Explore"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.COMMUTE, 
                selected_icon=ft.icons.COMMUTE_ROUNDED, 
                label="Commute"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.BOOKMARK_BORDER, 
                selected_icon=ft.icons.BOOKMARK, 
                label="Favorites"
            ),
        ],
        on_change=navigate
    )

    # 设置 AppBar
    def exit_app(e):
        page.window_close()

    page.appbar = ft.AppBar(
        leading=ft.Text("App Title"),
        center_title=True,
        bgcolor=ft.colors.SURFACE_VARIANT,
        actions=[
            ft.IconButton(ft.icons.INFO_OUTLINED),
            ft.IconButton(ft.icons.SETTINGS),
            ft.IconButton(ft.icons.CLOSE, on_click=exit_app),
        ],
    )

    # 添加内容到页面
    page.add(content)

    # 初始化导航栏
    page.navigation_bar.selected_index = 0
    navigate(None)

# 启动应用
ft.app(target=main)

3. 解释说明

关闭按钮及其功能实现:
在这段代码中,关闭按钮是一个IconButton,其图标为ft.icons.CLOSE,并且绑定了一个事件处理函数exit_app。当用户点击这个按钮时,会触发exit_app函数,从而关闭整个应用程序窗口。

**4. 运行效果,截图为证 **

在这里插入图片描述

第五步:去除窗口顶部桌面程序才有的最大化最小化关闭按钮和logo以及标题

1.编程思路

移动应用是手机使用的,所以要去除窗口顶部桌面程序才有的最大化最小化关闭按钮和logo以及标题。

2.示例代码


import flet as ft

def main(page: ft.Page):
    # 设置窗口大小
    page.window_width = 400
    page.window_height = 600
    
    # 设置窗口无边框
    page.window_frameless = True
    
    # 初始化内容
    content = ft.Text("Body!")

    # 更新页面内容的函数
    def navigate(e):
        if page.navigation_bar.selected_index == 0:
            content.value = "Explore Page Content!"
        elif page.navigation_bar.selected_index == 1:
            content.value = "Commute Page Content!"
        else:
            content.value = "Favorites Page Content!"

        page.update()

    # 设置导航栏
    page.navigation_bar = ft.NavigationBar(
        destinations=[
            ft.NavigationBarDestination(
                icon=ft.icons.EXPLORE, 
                selected_icon=ft.icons.EXPLORE_ROUNDED, 
                label="Explore"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.COMMUTE, 
                selected_icon=ft.icons.COMMUTE_ROUNDED, 
                label="Commute"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.BOOKMARK_BORDER, 
                selected_icon=ft.icons.BOOKMARK, 
                label="Favorites"
            ),
        ],
        on_change=navigate
    )

    # 设置 AppBar
    def exit_app(e):
        page.window_close()

    page.appbar = ft.AppBar(
        leading=ft.Text("App Title"),
        center_title=True,
        bgcolor=ft.colors.SURFACE_VARIANT,
        actions=[
            ft.IconButton(ft.icons.INFO_OUTLINED),
            ft.IconButton(ft.icons.SETTINGS),
            ft.IconButton(ft.icons.CLOSE, on_click=exit_app),
        ],
    )

    # 添加内容到页面
    page.add(content)

    # 初始化导航栏
    page.navigation_bar.selected_index = 0
    navigate(None)

# 启动应用
ft.app(target=main)

3. 解释说明
关键示例代码

# 设置窗口无边框
page.window_frameless = True

去除窗口顶部桌面程序才有的最大化最小化关闭按钮和logo以及标题就是设置窗口无边框。

**4. 运行效果,截图为证 **

在这里插入图片描述

第六步:添加页面安全区组件SafeArea

1.编程思路

SafeArea组件用于确保页面内容不会被屏幕边缘(如 iPhone 的刘海屏或 Android 的圆角屏)遮挡。它会在屏幕边缘留出一定的空间,使内容更加安全地显示。

2.示例代码


import flet as ft

def main(page: ft.Page):
    # 设置窗口大小
    page.window.width = 400
    page.window.height = 600
    
    # 设置窗口无边框
    page.window.frameless = True
    
    # 初始化内容
    content = ft.Text("Body!")

    # 更新页面内容的函数
    def navigate(e):
        if page.navigation_bar.selected_index == 0:
            content.value = "Explore Page Content!"
        elif page.navigation_bar.selected_index == 1:
            content.value = "Commute Page Content!"
        else:
            content.value = "Favorites Page Content!"

        page.update()

    # 设置导航栏
    page.navigation_bar = ft.NavigationBar(
        destinations=[
            ft.NavigationBarDestination(
                icon=ft.icons.EXPLORE, 
                selected_icon=ft.icons.EXPLORE_ROUNDED, 
                label="Explore"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.COMMUTE, 
                selected_icon=ft.icons.COMMUTE_ROUNDED, 
                label="Commute"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.BOOKMARK_BORDER, 
                selected_icon=ft.icons.BOOKMARK, 
                label="Favorites"
            ),
        ],
        on_change=navigate
    )

    # 设置 AppBar
    def exit_app(e):
        page.window_close()

    page.appbar = ft.AppBar(
        leading=ft.Text("App Title"),
        center_title=True,
        bgcolor=ft.colors.SURFACE_VARIANT,
        actions=[
            ft.IconButton(ft.icons.INFO_OUTLINED),
            ft.IconButton(ft.icons.SETTINGS),
            ft.IconButton(ft.icons.CLOSE, on_click=exit_app),
        ],
    )

    # 包裹内容在 SafeArea 组件内
    safe_area_content = ft.SafeArea(content)

    # 添加内容到页面
    page.add(safe_area_content)

    # 初始化导航栏
    page.navigation_bar.selected_index = 0
    navigate(None)

# 启动应用
ft.app(target=main)

3. 解释说明

SafeArea组件的作用

SafeArea组件用于确保页面内容不会被屏幕边缘(如 iPhone 的刘海屏或 Android 的圆角屏)遮挡。它会在屏幕边缘留出一定的空间,使内容更加安全地显示。

如何使用SafeArea组件

创建SafeArea组件:

safe_area_content = ft.SafeArea(content)

将内容包裹在SafeArea组件内:

page.add(safe_area_content)

这样,content控件会被包裹在一个SafeArea组件内,确保内容不会被屏幕边缘遮挡。

**4. 运行效果,截图为证 **

在这里插入图片描述

第七步:修改导航栏按钮名称和三个页面显示文字内容

1.编程思路

修改导航栏按钮名称和三个页面显示文字内容,对应任务目标。

2.示例代码


import flet as ft

def main(page: ft.Page):
    # 设置窗口大小
    page.window.width = 400
    page.window.height = 600
    
    # 设置窗口无边框
    page.window.frameless = True
    
    # 初始化内容
    content = ft.Text("Body!")

    # 更新页面内容的函数
    def navigate(e):
        if page.navigation_bar.selected_index == 0:
            content.value = "主页内容!"
        elif page.navigation_bar.selected_index == 1:
            content.value = "清单内容!"
        else:
            content.value = "关于内容!"

        page.update()

    # 设置导航栏
    page.navigation_bar = ft.NavigationBar(
        destinations=[
            ft.NavigationBarDestination(
                icon=ft.icons.HOME, 
                selected_icon=ft.icons.HOME_ROUNDED, 
                label="主页"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.LIST, 
                selected_icon=ft.icons.LIST_ALT, 
                label="清单"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.INFO, 
                selected_icon=ft.icons.INFO_ROUNDED, 
                label="关于"
            ),
        ],
        on_change=navigate
    )

    # 设置 AppBar
    def exit_app(e):
        page.window_close()

    page.appbar = ft.AppBar(
        leading=ft.Text("App Title"),
        center_title=True,
        bgcolor=ft.colors.SURFACE_VARIANT,
        actions=[
            ft.IconButton(ft.icons.INFO_OUTLINED),
            ft.IconButton(ft.icons.SETTINGS),
            ft.IconButton(ft.icons.CLOSE, on_click=exit_app),
        ],
    )

    # 包裹内容在 SafeArea 组件内
    safe_area_content = ft.SafeArea(content)

    # 添加内容到页面
    page.add(safe_area_content)

    # 初始化导航栏
    page.navigation_bar.selected_index = 0
    navigate(None)

# 启动应用
ft.app(target=main)

3. 解释说明

A.更新页面内容的函数 navigate(e)

def navigate(e):
    if page.navigation_bar.selected_index == 0:
        content.value = "主页内容!"
    elif page.navigation_bar.selected_index == 1:
        content.value = "清单内容!"
    else:
        content.value = "关于内容!"

    page.update()

解释:

将原来的英文内容替换为中文内容:
“Explore Page Content!” 替换为 “主页内容!”
“Commute Page Content!” 替换为 “清单内容!”
“Favorites Page Content!” 替换为 “关于内容!”

B.设置导航栏

page.navigation_bar = ft.NavigationBar(
    destinations=[
        ft.NavigationBarDestination(
            icon=ft.icons.HOME, 
            selected_icon=ft.icons.HOME_ROUNDED, 
            label="主页"
        ),
        ft.NavigationBarDestination(
            icon=ft.icons.LIST, 
            selected_icon=ft.icons.LIST_ALT, 
            label="清单"
        ),
        ft.NavigationBarDestination(
            icon=ft.icons.INFO, 
            selected_icon=ft.icons.INFO_ROUNDED, 
            label="关于"
        ),
    ],
    on_change=navigate
)

解释:

将原来的英文标签替换为中文标签:

“Explore” 替换为 “主页”
“Commute” 替换为 “清单”
“Favorites” 替换为 “关于”
更改了图标:

ft.icons.EXPLORE 替换为 ft.icons.HOME
ft.icons.EXPLORE_ROUNDED 替换为 ft.icons.HOME_ROUNDED
ft.icons.COMMUTE 替换为 ft.icons.LIST
ft.icons.COMMUTE_ROUNDED 替换为 ft.icons.LIST_ALT
ft.icons.BOOKMARK_BORDER 替换为 ft.icons.INFO
ft.icons.BOOKMARK 替换为 ft.icons.INFO_ROUNDED

**4. 运行效果,截图为证 **
在这里插入图片描述

第八步:关于页面添加作者文字信息

1.编程思路

给页面添加内容,这一次给关于页面添加作者文字信息

2.示例代码


import flet as ft

def main(page: ft.Page):
    # 设置窗口大小
    page.window.width = 400
    page.window.height = 600
    
    # 设置窗口无边框
    page.window.frameless = True
    
    # 初始化内容
    content = ft.Column(
        [
            ft.Text("Body!", size=20),
        ],
        alignment=ft.MainAxisAlignment.CENTER,
    )

    # 更新页面内容的函数
    def navigate(e):
        if page.navigation_bar.selected_index == 0:
            content.controls = [
                ft.Text("主页内容!", size=20)
            ]
        elif page.navigation_bar.selected_index == 1:
            content.controls = [
                ft.Text("清单内容!", size=20)
            ]
        else:
            content.controls = [
                ft.Text("关于内容!", size=20),
                ft.Divider(),
                ft.Text("购物清单助手1.0", size=16),
                ft.Text("作者:传奇开心果", size=14),
                ft.Text("微信:lxm1093220242", size=14),
            ]

        page.update()

    # 设置导航栏
    page.navigation_bar = ft.NavigationBar(
        destinations=[
            ft.NavigationBarDestination(
                icon=ft.icons.HOME, 
                selected_icon=ft.icons.HOME_ROUNDED, 
                label="主页"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.LIST, 
                selected_icon=ft.icons.LIST_ALT, 
                label="清单"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.INFO, 
                selected_icon=ft.icons.INFO_ROUNDED, 
                label="关于"
            ),
        ],
        on_change=navigate
    )

    # 设置 AppBar
    def exit_app(e):
        page.window_close()

    page.appbar = ft.AppBar(
        leading=ft.Text("App Title"),
        center_title=True,
        bgcolor=ft.colors.SURFACE_VARIANT,
        actions=[
            ft.IconButton(ft.icons.INFO_OUTLINED),
            ft.IconButton(ft.icons.SETTINGS),
            ft.IconButton(ft.icons.CLOSE, on_click=exit_app),
        ],
    )

    # 包裹内容在 SafeArea 组件内
    safe_area_content = ft.SafeArea(content)

    # 添加内容到页面
    page.add(safe_area_content)

    # 初始化导航栏
    page.navigation_bar.selected_index = 0
    navigate(None)

# 启动应用
ft.app(target=main)

3. 解释说明

在提供的代码中,已经实现了当用户选择“关于”页面时展示相关信息的功能。具体来说,在navigate函数内部,当page.navigation_bar.selected_index等于2时(即选择了第三个选项“关于”),content.controls列表被更新为包含多个ft.Text组件,这些组件展示了应用的版本信息以及作者的联系方式。

关于页面内容解析

“关于内容!”:标题文本。
“购物清单助手1.0”:应用名称和版本号。
“作者:传奇开心果”:作者的名字。
“微信:lxm1093220242”:作者的联系方式。

如何工作

每当用户点击底部导航栏中的一个选项时,on_change事件触发navigate函数。此函数检查当前选中的导航项索引,并根据索引值更新content.controls的内容。当索引为2时,表示用户选择了“关于”页面,此时会显示上述提到的信息。

代码结构

使用ft.Column来组织页面上的内容。
navigate函数负责根据不同导航项的选择动态更新页面内容。
应用启动时,默认显示“主页”页面的内容,并且导航栏的初始选中项为“主页”。
通过这种方式,你可以轻松地为“关于”页面添加或修改任何信息,只需更改navigate函数中相关部分即可。

**4. 运行效果,截图为证 **

在这里插入图片描述

第九步:给关于页面添加图片

1.编程思路

给关于页面添加作者logo图片,达到图文并茂效果。

2.示例代码


import flet as ft

def main(page: ft.Page):
    # 设置窗口大小
    page.window.width = 400
    page.window.height = 600
    
    # 设置窗口无边框
    page.window.frameless = True
    
    # 初始化内容
    content = ft.Column(
        [
            ft.Text("Body!", size=20),
        ],
        alignment=ft.MainAxisAlignment.CENTER,
    )

    # 更新页面内容的函数
    def navigate(e):
        if page.navigation_bar.selected_index == 0:
            content.controls = [
                ft.Text("主页内容!", size=20)
            ]
        elif page.navigation_bar.selected_index == 1:
            content.controls = [
                ft.Text("清单内容!", size=20)
            ]
        else:
            content.controls = [
                ft.Text("关于内容!", size=20),
                ft.Divider(),
                ft.Image(src="logo传奇开心果.png", width=100, height=100),
                ft.Text("购物清单助手1.0", size=16),
                ft.Text("作者:传奇开心果", size=14),
                ft.Text("微信:lxm1093220242", size=14),
            ]

        page.update()

    # 设置导航栏
    page.navigation_bar = ft.NavigationBar(
        destinations=[
            ft.NavigationBarDestination(
                icon=ft.icons.HOME, 
                selected_icon=ft.icons.HOME_ROUNDED, 
                label="主页"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.LIST, 
                selected_icon=ft.icons.LIST_ALT, 
                label="清单"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.INFO, 
                selected_icon=ft.icons.INFO_ROUNDED, 
                label="关于"
            ),
        ],
        on_change=navigate
    )

    # 设置 AppBar
    def exit_app(e):
        page.window_close()

    page.appbar = ft.AppBar(
        leading=ft.Text("App Title"),
        center_title=True,
        bgcolor=ft.colors.SURFACE_VARIANT,
        actions=[
            ft.IconButton(ft.icons.INFO_OUTLINED),
            ft.IconButton(ft.icons.SETTINGS),
            ft.IconButton(ft.icons.CLOSE, on_click=exit_app),
        ],
    )

    # 包裹内容在 SafeArea 组件内
    safe_area_content = ft.SafeArea(content)

    # 添加内容到页面
    page.add(safe_area_content)

    # 初始化导航栏
    page.navigation_bar.selected_index = 0
    navigate(None)

# 启动应用
ft.app(target=main)

3. 解释说明

给关于页面添加作者logo图片,设置样式设置尺寸居中对齐。

**4. 运行效果,截图为证 **
在这里插入图片描述

第十步:给关于页面内容进一步修改样式

1.编程思路

给关于页面内容进一步修改样式尺寸,水平和垂直居中对齐。

2.示例代码


import flet as ft

def main(page: ft.Page):
    # 设置窗口大小
    page.window.width = 400
    page.window.height = 600
    
    # 设置窗口无边框
    page.window.frameless = True
    
    # 初始化内容
    content = ft.Column(
        [
            ft.Text("Body!", size=20),
        ],
        alignment=ft.MainAxisAlignment.CENTER,
        horizontal_alignment=ft.CrossAxisAlignment.CENTER,
    )

    # 更新页面内容的函数
    def navigate(e):
        if page.navigation_bar.selected_index == 0:
            content.controls = [
                ft.Text("主页内容!", size=20)
            ]
        elif page.navigation_bar.selected_index == 1:
            content.controls = [
                ft.Text("清单内容!", size=20)
            ]
        else:
            content.controls = [
                ft.Text("关于内容!", size=20),
                ft.Divider(),
                ft.Image(src="logo传奇开心果.png", width=100, height=100),
                ft.Text("购物清单助手1.0", size=16),
                ft.Text("作者:传奇开心果", size=14),
                ft.Text("微信:lxm1093220242", size=14),
            ]

        page.update()

    # 设置导航栏
    page.navigation_bar = ft.NavigationBar(
        destinations=[
            ft.NavigationBarDestination(
                icon=ft.icons.HOME, 
                selected_icon=ft.icons.HOME_ROUNDED, 
                label="主页"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.LIST, 
                selected_icon=ft.icons.LIST_ALT, 
                label="清单"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.INFO, 
                selected_icon=ft.icons.INFO_ROUNDED, 
                label="关于"
            ),
        ],
        on_change=navigate
    )

    # 设置 AppBar
    def exit_app(e):
        page.window_close()

    page.appbar = ft.AppBar(
        leading=ft.Text("App Title"),
        center_title=True,
        bgcolor=ft.colors.SURFACE_VARIANT,
        actions=[
            ft.IconButton(ft.icons.INFO_OUTLINED),
            ft.IconButton(ft.icons.SETTINGS),
            ft.IconButton(ft.icons.CLOSE, on_click=exit_app),
        ],
    )

    # 包裹内容在 SafeArea 组件内
    safe_area_content = ft.SafeArea(content)

    # 添加内容到页面
    page.add(safe_area_content)

    # 初始化导航栏
    page.navigation_bar.selected_index = 0
    navigate(None)

# 启动应用
ft.app(target=main)

3. 解释说明

关于页面图文尺寸调整,水平和垂直居中。提高布局的美观性。
在提供的代码中,你已经实现了关于页面的图文内容布局设置,以提高美观性和用户体验。以下是关于页面的具体布局和功能概述:

关于页面的图文内容布局

标题:

ft.Text(“关于内容!”, size=20):作为页面的标题。
分割线:

ft.Divider():用于视觉上分隔不同部分的内容。
作者头像:

ft.Image(src=“logo传奇开心果.png”, width=100, height=100):展示作者的头像或应用的Logo。
应用版本信息:

ft.Text(“购物清单助手1.0”, size=16):显示应用的名称和版本号。
作者信息:

ft.Text(“作者:传奇开心果”, size=14):显示作者的名字。
ft.Text(“微信:lxm1093220242”, size=14):显示作者的联系方式。

关于页面布局设置

整体布局:

使用ft.Column组件来垂直排列所有内容,并设置了居中对齐:
python
content = ft.Column(
[
ft.Text(“Body!”, size=20),
],
alignment=ft.MainAxisAlignment.CENTER,
horizontal_alignment=ft.CrossAxisAlignment.CENTER,
)

导航栏事件处理:

A.在navigate函数中,根据不同的导航项索引更新页面内容:

def navigate(e):
    if page.navigation_bar.selected_index == 0:
        content.controls = [
            ft.Text("主页内容!", size=20)
        ]
    elif page.navigation_bar.selected_index == 1:
        content.controls = [
            ft.Text("清单内容!", size=20)
        ]
    else:
        content.controls = [
            ft.Text("关于内容!", size=20),
            ft.Divider(),
            ft.Image(src="logo传奇开心果.png", width=100, height=100),
            ft.Text("购物清单助手1.0", size=16),
            ft.Text("作者:传奇开心果", size=14),
            ft.Text("微信:lxm1093220242", size=14),
        ]

    page.update()
    

B.其他页面元素:

设置了导航栏、App Bar 和关闭按钮等功能。

C.总结

通过以上设置,你实现了以下效果:

页面布局美观且内容清晰。
图文结合,增加了页面的吸引力。
动态更新页面内容,提高了用户体验。
这样可以确保用户在访问“关于”页面时能够获得详细且美观的信息展示。

**4. 运行效果,截图为证 **

在这里插入图片描述

第十一步:给appbar添加增加删除和保存按钮

1.编程思路

给appbar添加增加删除和保存按钮,将来进行业务操作。

2.示例代码


import flet as ft

def main(page: ft.Page):
    # 设置窗口大小
    page.window.width = 400
    page.window.height = 600
    
    # 设置窗口无边框
    page.window.frameless = True
    
    # 初始化内容
    content = ft.Column(
        [
            ft.Text("Body!", size=20),
        ],
        alignment=ft.MainAxisAlignment.CENTER,
        horizontal_alignment=ft.CrossAxisAlignment.CENTER,
    )

    # 更新页面内容的函数
    def navigate(e):
        if page.navigation_bar.selected_index == 0:
            content.controls = [
                ft.Text("主页内容!", size=20)
            ]
        elif page.navigation_bar.selected_index == 1:
            content.controls = [
                ft.Text("清单内容!", size=20)
            ]
        else:
            content.controls = [
                ft.Text("关于内容!", size=20),
                ft.Divider(),
                ft.Image(src="legendary_happy_nut.png", width=100, height=100),
                ft.Text("购物清单助手1.0", size=16),
                ft.Text("作者:传奇开心果", size=14),
                ft.Text("微信:lxm1093220242", size=14),
            ]

        page.update()

    # 设置导航栏
    page.navigation_bar = ft.NavigationBar(
        destinations=[
            ft.NavigationBarDestination(
                icon=ft.icons.HOME, 
                selected_icon=ft.icons.HOME_ROUNDED, 
                label="主页"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.LIST, 
                selected_icon=ft.icons.LIST_ALT, 
                label="清单"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.INFO, 
                selected_icon=ft.icons.INFO_ROUNDED, 
                label="关于"
            ),
        ],
        on_change=navigate
    )

    # 设置 AppBar
    def add_action(e):
        print("增加操作")

    def delete_action(e):
        print("删除操作")

    def save_action(e):
        print("保存操作")

    def exit_app(e):
        page.window_close()

    page.appbar = ft.AppBar(
        leading=ft.Text("App Title"),
        center_title=True,
        bgcolor=ft.colors.SURFACE_VARIANT,
        actions=[
            ft.IconButton(ft.icons.ADD, on_click=add_action),
            ft.IconButton(ft.icons.DELETE, on_click=delete_action),
            ft.IconButton(ft.icons.SAVE, on_click=save_action),
            ft.IconButton(ft.icons.CLOSE, on_click=exit_app),
        ],
    )

    # 包裹内容在 SafeArea 组件内
    safe_area_content = ft.SafeArea(content)

    # 添加内容到页面
    page.add(safe_area_content)

    # 初始化导航栏
    page.navigation_bar.selected_index = 0
    navigate(None)

# 启动应用
ft.app(target=main)

3. 解释说明

在这段代码中,你为 AppBar 添加了三个按钮:增加、删除和保存。下面是具体的解释和实现细节:

AppBar 按钮功能

增加按钮 (ft.IconButton(ft.icons.ADD, on_click=add_action)):

图标:

使用 ft.icons.ADD 图标表示增加操作。

点击事件:

当用户点击此按钮时,会调用 add_action 函数并打印 “增加操作”。
删除按钮 (ft.IconButton(ft.icons.DELETE, on_click=delete_action)):

***图标: ***

使用 ft.icons.DELETE 图标表示删除操作。

***点击事件: ***

当用户点击此按钮时,会调用 delete_action 函数并打印 “删除操作”。

保存按钮 :

(ft.IconButton(ft.icons.SAVE, on_click=save_action)):

***图标: ***
使用 ft.icons.SAVE 图标表示保存操作。

***点击事件: ***

当用户点击此按钮时,会调用 save_action 函数并打印 “保存操作”。

**4. 运行效果,截图为证 **

在这里插入图片描述

第十二步:设置标题栏appbar的标题文字样式

1.编程思路

设置标题栏appbar的标题文字样式,提高标题栏的协调美观性。

2.示例代码


import flet as ft

def main(page: ft.Page):
    # 设置窗口大小
    page.window.width = 400
    page.window.height = 600
    
    # 设置窗口无边框
    page.window.frameless = True
    
    # 初始化内容
    content = ft.Column(
        [
            ft.Text("Body!", size=20),
        ],
        alignment=ft.MainAxisAlignment.CENTER,
        horizontal_alignment=ft.CrossAxisAlignment.CENTER,
    )

    # 更新页面内容的函数
    def navigate(e):
        if page.navigation_bar.selected_index == 0:
            content.controls = [
                ft.Text("主页内容!", size=20)
            ]
        elif page.navigation_bar.selected_index == 1:
            content.controls = [
                ft.Text("清单内容!", size=20)
            ]
        else:
            content.controls = [
                ft.Text("关于内容!", size=20),
                ft.Divider(),
                ft.Image(src="logo传奇开心果.png", width=100, height=100),
                ft.Column([
                    ft.Text("购物清单助手移动应用app1.0", size=14),
                    ft.Text("作者:传奇开心果", size=14),
                    ft.Text("微信:lxm1093220242", size=14),
                ], alignment=ft.MainAxisAlignment.START),
            ]

        page.update()

    # 设置导航栏
    page.navigation_bar = ft.NavigationBar(
        destinations=[
            ft.NavigationBarDestination(
                icon=ft.icons.HOME, 
                selected_icon=ft.icons.HOME_ROUNDED, 
                label="主页"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.LIST, 
                selected_icon=ft.icons.LIST_ALT, 
                label="清单"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.INFO, 
                selected_icon=ft.icons.INFO_ROUNDED, 
                label="关于"
            ),
        ],
        on_change=navigate
    )

    # 设置 AppBar
    def add_action(e):
        print("增加操作")

    def delete_action(e):
        print("删除操作")

    def save_action(e):
        print("保存操作")

    def exit_app(e):
        page.window_close()

    page.appbar = ft.AppBar(
        leading=ft.Row([
            ft.Text("购物清单助手1.0", size=14),
        ], alignment=ft.MainAxisAlignment.START),
        center_title=False,
        bgcolor=ft.colors.SURFACE_VARIANT,
        actions=[
            ft.IconButton(ft.icons.ADD, on_click=add_action),
            ft.IconButton(ft.icons.DELETE, on_click=delete_action),
            ft.IconButton(ft.icons.SAVE, on_click=save_action),
            ft.IconButton(ft.icons.CLOSE, on_click=exit_app),
        ],
    )

    # 包裹内容在 SafeArea 组件内
    safe_area_content = ft.SafeArea(content)

    # 添加内容到页面
    page.add(safe_area_content)

    # 初始化导航栏
    page.navigation_bar.selected_index = 0
    navigate(None)

# 启动应用
ft.app(target=main)

3. 解释说明

这段代码设置了 flet 框架中的 AppBar 组件,用于显示应用程序的标题栏。下面是每个部分的详细解释:

leading 属性:

leading=ft.Row([
    ft.Text("购物清单助手1.0", size=14),
], alignment=ft.MainAxisAlignment.START),

leading 属性定义了 AppBar 的左侧内容。
使用 ft.Row 布局容器将文本组件 ft.Text 包含其中。
ft.Text 显示文本“购物清单助手1.0”,字体大小为 14。
center_title 属性:

center_title=False,

center_title 属性控制是否居中显示标题。
设置为 False 表示不居中显示标题,而是按照 leading 定义的位置显示。
bgcolor 属性:

bgcolor=ft.colors.SURFACE_VARIANT,

bgcolor 属性设置 AppBar 的背景颜色。
使用 ft.colors.SURFACE_VARIANT 颜色,这是一个预定义的颜色值。
actions 属性:

actions=[
    ft.IconButton(ft.icons.ADD, on_click=add_action),
    ft.IconButton(ft.icons.DELETE, on_click=delete_action),
    ft.IconButton(ft.icons.SAVE, on_click=save_action),
    ft.IconButton(ft.icons.CLOSE, on_click=exit_app),
],

actions 属性定义了 AppBar 右侧的一系列图标按钮。
每个 IconButton 表示一个带有图标的按钮,并且绑定了点击事件处理函数。
ft.IconButton(ft.icons.ADD, on_click=add_action):添加按钮,点击时调用 add_action 函数。
ft.IconButton(ft.icons.DELETE, on_click=delete_action):删除按钮,点击时调用 delete_action 函数。
ft.IconButton(ft.icons.SAVE, on_click=save_action):保存按钮,点击时调用 save_action 函数。
ft.IconButton(ft.icons.CLOSE, on_click=exit_app):关闭按钮,点击时调用 exit_app 函数。
通过这些配置,AppBar 组件将显示左侧的文本“购物清单助手1.0”,右侧显示四个功能按钮,分别为添加、删除、保存和关闭。整个 AppBar 的背景颜色为 SURFACE_VARIANT,并且标题不居中显示。

**4. 运行效果,截图为证 **
在这里插入图片描述

第十三步:给主页面添加输入框和列表视图组件

1.编程思路

给主页面添加选购商品输入框输入商品名称和列表视图组件显示。设置样式,实现逻辑功能。

2.示例代码


import flet as ft

def main(page: ft.Page):
    # 设置窗口大小
    page.window.width = 400
    page.window.height = 600
    
    # 设置窗口无边框
    page.window.frameless = True
    
    # 初始化内容
    content = ft.Column(
        [
            ft.Text("Body!", size=20),
        ],
        alignment=ft.MainAxisAlignment.CENTER,
        horizontal_alignment=ft.CrossAxisAlignment.CENTER,
    )

    # 输入框和列表视图
    input_text = ft.TextField(label="输入商品名称")
    items_list = ft.ListView(expand=1, spacing=10, padding=20, auto_scroll=True)

    # 更新页面内容的函数
    def navigate(e):
        if page.navigation_bar.selected_index == 0:
            content.controls = [
                ft.Column([
                    input_text,
                    items_list,
                ], alignment=ft.MainAxisAlignment.START)
            ]
        elif page.navigation_bar.selected_index == 1:
            content.controls = [
                ft.Text("清单内容!", size=20)
            ]
        else:
            content.controls = [
                ft.Text("关于内容!", size=20),
                ft.Divider(),
                ft.Image(src="logo传奇开心果.png", width=100, height=100),
                ft.Column([
                    ft.Text("购物清单助手移动应用app1.0", size=14),
                    ft.Text("作者:传奇开心果", size=14),
                    ft.Text("微信:lxm1093220242", size=14),
                ], alignment=ft.MainAxisAlignment.START),
            ]

        page.update()

    # 设置导航栏
    page.navigation_bar = ft.NavigationBar(
        destinations=[
            ft.NavigationBarDestination(
                icon=ft.icons.HOME, 
                selected_icon=ft.icons.HOME_ROUNDED, 
                label="主页"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.LIST, 
                selected_icon=ft.icons.LIST_ALT, 
                label="清单"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.INFO, 
                selected_icon=ft.icons.INFO_ROUNDED, 
                label="关于"
            ),
        ],
        on_change=navigate
    )

    # 设置 AppBar
    def add_action(e):
        if input_text.value:
            items_list.controls.append(ft.Text(input_text.value))
            input_text.value = ""
            page.update()

    def delete_action(e):
        print("删除操作")

    def save_action(e):
        print("保存操作")

    def exit_app(e):
        page.window_close()

    page.appbar = ft.AppBar(
        leading=ft.Row([
            ft.Text("购物清单助手1.0", size=14),
        ], alignment=ft.MainAxisAlignment.START),
        center_title=False,
        bgcolor=ft.colors.SURFACE_VARIANT,
        actions=[
            ft.IconButton(ft.icons.ADD, on_click=add_action),
            ft.IconButton(ft.icons.DELETE, on_click=delete_action),
            ft.IconButton(ft.icons.SAVE, on_click=save_action),
            ft.IconButton(ft.icons.CLOSE, on_click=exit_app),
        ],
    )

    # 包裹内容在 SafeArea 组件内
    safe_area_content = ft.SafeArea(content)

    # 添加内容到页面
    page.add(safe_area_content)

    # 初始化导航栏
    page.navigation_bar.selected_index = 0
    navigate(None)

# 启动应用
ft.app(target=main)

3. 解释说明

输入框和列表视图

input_text = ft.TextField(label="输入商品名称")
items_list = ft.ListView(expand=1, spacing=10, padding=20, auto_scroll=True)
input_text:创建一个文本输入框 (TextField),标签为 “输入商品名称”。
items_list:创建一个列表视图 (ListView),用于显示列表项。
expand=1:使列表视图扩展以填充可用空间。
spacing=10:设置列表项之间的间距为 10。
padding=20:设置列表视图的内边距为 20。
auto_scroll=True:启用自动滚动功能。

更新页面内容的函数

def navigate(e):
    if page.navigation_bar.selected_index == 0:
        content.controls = [
            ft.Column([
                input_text,
                items_list,
            ], alignment=ft.MainAxisAlignment.START)
        ]
navigate 函数:根据导航栏的选择更新页面内容。
if page.navigation_bar.selected_index == 0::如果当前选中的导航栏索引为 0(即“主页”)。
content.controls:更新 content 的子控件列表。
创建一个新的 Column 容器,包含 input_text 和 items_list。
alignment=ft.MainAxisAlignment.START:设置新 Column 的垂直对齐方式为顶部对齐。

总结

这段代码实现了以下功能:
创建了一个文本输入框和一个列表视图。
当导航栏选择“主页”时,页面内容更新为包含输入框和列表视图的布局。
这样可以动态地根据用户的选择更新页面内容,使得界面更加灵活和响应式

4. 运行效果,截图为证
在这里插入图片描述

第十四步:每个条目前面都有一个复选框

1.编程思路

点击添加按钮时,在列表视图中显示输入的商品名称,并且每个条目前面都有一个复选框。

2.示例代码


import flet as ft

def main(page: ft.Page):
    # 设置窗口大小
    page.window_width = 400
    page.window_height = 600
    # 设置窗口无边框
    page.window.frameless = True
    
    # 初始化内容
    content = ft.Column(
        [
            ft.Text("Body!", size=20),
        ],
        alignment=ft.MainAxisAlignment.CENTER,
        horizontal_alignment=ft.CrossAxisAlignment.CENTER,
    )

    # 输入框和列表视图
    input_text = ft.TextField(label="输入商品名称")
    items_list = ft.ListView(expand=1, spacing=10, padding=20, auto_scroll=True)

    # 更新页面内容的函数
    def navigate(e):
        if page.navigation_bar.selected_index == 0:
            content.controls = [
                ft.Column([
                    input_text,
                    items_list,
                ], alignment=ft.MainAxisAlignment.START)
            ]
        elif page.navigation_bar.selected_index == 1:
            content.controls = [
                ft.Text("清单内容!", size=20)
            ]
        else:
            content.controls = [
                ft.Text("关于内容!", size=20),
                ft.Divider(),
                ft.Image(src="logo传奇开心果.png", width=100, height=100),
                ft.Column([
                    ft.Text("购物清单助手移动应用app1.0", size=14),
                    ft.Text("作者:传奇开心果", size=14),
                    ft.Text("微信:lxm1093220242", size=14),
                ], alignment=ft.MainAxisAlignment.START),
            ]

        page.update()

    # 设置导航栏
    page.navigation_bar = ft.NavigationBar(
        destinations=[
            ft.NavigationBarDestination(
                icon=ft.icons.HOME, 
                selected_icon=ft.icons.HOME_ROUNDED, 
                label="主页"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.LIST, 
                selected_icon=ft.icons.LIST_ALT, 
                label="清单"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.INFO, 
                selected_icon=ft.icons.INFO_ROUNDED, 
                label="关于"
            ),
        ],
        on_change=navigate
    )

    # 设置 AppBar
    def add_action(e):
        if input_text.value:
            item = ft.ListTile(
                leading=ft.Checkbox(),
                title=ft.Text(input_text.value),
            )
            items_list.controls.append(item)
            input_text.value = ""
            page.update()

    def delete_action(e):
        print("删除操作")

    def save_action(e):
        print("保存操作")

    def exit_app(e):
        page.window_close()

    page.appbar = ft.AppBar(
        leading=ft.Row([
            ft.Text("购物清单助手1.0", size=14),
        ], alignment=ft.MainAxisAlignment.START),
        center_title=False,
        bgcolor=ft.colors.SURFACE_VARIANT,
        actions=[
            ft.IconButton(ft.icons.ADD, on_click=add_action),
            ft.IconButton(ft.icons.DELETE, on_click=delete_action),
            ft.IconButton(ft.icons.SAVE, on_click=save_action),
            ft.IconButton(ft.icons.CLOSE, on_click=exit_app),
        ],
    )

    # 包裹内容在 SafeArea 组件内
    safe_area_content = ft.SafeArea(content)

    # 添加内容到页面
    page.add(safe_area_content)

    # 初始化导航栏
    page.navigation_bar.selected_index = 0
    navigate(None)

# 启动应用
ft.app(target=main)

3. 解释说明

添加操作

def add_action(e):
    if input_text.value:
        item = ft.ListTile(
            leading=ft.Checkbox(),
            title=ft.Text(input_text.value),
        )
        items_list.controls.append(item)
        input_text.value = ""
        page.update()

add_action 函数:处理添加按钮的点击事件。
如果 input_text 的值不为空,则创建一个新的 ListTile。
leading=ft.Checkbox():在 ListTile 的左侧添加一个复选框。
title=ft.Text(input_text.value):在 ListTile 的中间显示输入的商品名称。
将新创建的 ListTile 添加到 items_list 的 controls 列表中。
清空 input_text 的值。
调用 page.update() 更新页面。
当点击添加按钮时,在列表视图中显示输入的商品名称,并且每个条目前面都有一个复选框。

**4. 运行效果,截图为证 **
在这里插入图片描述

第十五步:实现勾选商品删除功能

1.编程思路

给复选框打对勾,点击删除按钮,实现勾选商品删除功能

2.示例代码


import flet as ft

def main(page: ft.Page):
    # 设置窗口大小
    page.window_width = 400
    page.window_height = 600
    # 设置窗口无边框
    page.window.frameless = True
    
    
    # 初始化内容
    content = ft.Column(
        [
            ft.Text("Body!", size=20),
        ],
        alignment=ft.MainAxisAlignment.CENTER,
        horizontal_alignment=ft.CrossAxisAlignment.CENTER,
    )

    # 输入框和列表视图
    input_text = ft.TextField(label="输入商品名称")
    items_list = ft.ListView(expand=1, spacing=10, padding=20, auto_scroll=True)

    # 更新页面内容的函数
    def navigate(e):
        if page.navigation_bar.selected_index == 0:
            content.controls = [
                ft.Column([
                    input_text,
                    items_list,
                ], alignment=ft.MainAxisAlignment.START)
            ]
        elif page.navigation_bar.selected_index == 1:
            content.controls = [
                ft.Text("清单内容!", size=20)
            ]
        else:
            content.controls = [
                ft.Text("关于内容!", size=20),
                ft.Divider(),
                ft.Image(src="logo传奇开心果.png", width=100, height=100),
                ft.Column([
                    ft.Text("购物清单助手移动应用app1.0", size=14),
                    ft.Text("作者:传奇开心果", size=14),
                    ft.Text("微信:lxm1093220242", size=14),
                ], alignment=ft.MainAxisAlignment.START),
            ]

        page.update()

    # 设置导航栏
    page.navigation_bar = ft.NavigationBar(
        destinations=[
            ft.NavigationBarDestination(
                icon=ft.icons.HOME, 
                selected_icon=ft.icons.HOME_ROUNDED, 
                label="主页"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.LIST, 
                selected_icon=ft.icons.LIST_ALT, 
                label="清单"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.INFO, 
                selected_icon=ft.icons.INFO_ROUNDED, 
                label="关于"
            ),
        ],
        on_change=navigate
    )

    # 设置 AppBar
    def add_action(e):
        if input_text.value:
            item = ft.ListTile(
                leading=ft.Checkbox(),
                title=ft.Text(input_text.value),
                on_click=lambda e: toggle_checkbox(e.control),
            )
            items_list.controls.append(item)
            input_text.value = ""
            page.update()

    def delete_action(e):
        checked_items = [item for item in items_list.controls if item.leading.value]
        for item in checked_items:
            items_list.controls.remove(item)
        page.update()

    def save_action(e):
        saved_items = [item.title.value for item in items_list.controls if item.leading.value]
        print("保存的商品:", saved_items)

    def exit_app(e):
        page.window_close()

    def toggle_checkbox(control):
        control.leading.value = not control.leading.value
        page.update()

    page.appbar = ft.AppBar(
        leading=ft.Row([
            ft.Text("购物清单助手1.0", size=14),
        ], alignment=ft.MainAxisAlignment.START),
        center_title=False,
        bgcolor=ft.colors.SURFACE_VARIANT,
        actions=[
            ft.IconButton(ft.icons.ADD, on_click=add_action),
            ft.IconButton(ft.icons.DELETE, on_click=delete_action),
            ft.IconButton(ft.icons.SAVE, on_click=save_action),
            ft.IconButton(ft.icons.CLOSE, on_click=exit_app),
        ],
    )

    # 包裹内容在 SafeArea 组件内
    safe_area_content = ft.SafeArea(content)

    # 添加内容到页面
    page.add(safe_area_content)

    # 初始化导航栏
    page.navigation_bar.selected_index = 0
    navigate(None)

# 启动应用
ft.app(target=main)

3. 解释说明

实现删除操作

def delete_action(e):
    checked_items = [item for item in items_list.controls if item.leading.value]
    for item in checked_items:
        items_list.controls.remove(item)
    page.update()

delete_action 函数:处理删除按钮的点击事件。
使用列表推导式获取所有被勾选的 ListTile。
遍历这些被勾选的 ListTile 并从 items_list 的 controls 列表中移除它们。
调用 page.update() 更新页面。

4. 运行效果,截图为证

在这里插入图片描述

第十六步:给清单页添加数据表组件DataTable

1.编程思路

给清单页添加数据表组件DataTable,实现主页输入框输入的商品被用户勾选,并且点击保存按钮以后显示在清单页面的数据表内。

2.示例代码


import flet as ft

def main(page: ft.Page):
    # 设置窗口大小
    page.window_width = 400
    page.window_height = 600
    # 设置窗口无边框
    page.window.frameless = True
    
    # 初始化内容
    content = ft.Column(
        [
            ft.Text("Body!", size=20),
        ],
        alignment=ft.MainAxisAlignment.CENTER,
        horizontal_alignment=ft.CrossAxisAlignment.CENTER,
    )

    # 输入框和列表视图
    input_text = ft.TextField(label="输入商品名称")
    items_list = ft.ListView(expand=1, spacing=10, padding=20, auto_scroll=True)
    data_table = ft.DataTable(
        columns=[
            ft.DataColumn(ft.Text("商品名称")),
            ft.DataColumn(ft.Text("是否勾选")),
        ],
        rows=[],
    )

    # 更新页面内容的函数
    def navigate(e):
        if page.navigation_bar.selected_index == 0:
            content.controls = [
                ft.Column([
                    input_text,
                    items_list,
                ], alignment=ft.MainAxisAlignment.START)
            ]
        elif page.navigation_bar.selected_index == 1:
            content.controls = [
                ft.Column([
                    data_table,
                ], alignment=ft.MainAxisAlignment.START)
            ]
        else:
            content.controls = [
                ft.Text("关于内容!", size=20),
                ft.Divider(),
                ft.Image(src="logo传奇开心果.png", width=100, height=100),
                ft.Column([
                    ft.Text("购物清单助手移动应用app1.0", size=14),
                    ft.Text("作者:传奇开心果", size=14),
                    ft.Text("微信:lxm1093220242", size=14),
                ], alignment=ft.MainAxisAlignment.START),
            ]

        page.update()

    # 设置导航栏
    page.navigation_bar = ft.NavigationBar(
        destinations=[
            ft.NavigationBarDestination(
                icon=ft.icons.HOME, 
                selected_icon=ft.icons.HOME_ROUNDED, 
                label="主页"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.LIST, 
                selected_icon=ft.icons.LIST_ALT, 
                label="清单"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.INFO, 
                selected_icon=ft.icons.INFO_ROUNDED, 
                label="关于"
            ),
        ],
        on_change=navigate
    )

    # 设置 AppBar
    def add_action(e):
        if input_text.value:
            item = ft.ListTile(
                leading=ft.Checkbox(),
                title=ft.Text(input_text.value),
                on_click=lambda e: toggle_checkbox(e.control),
            )
            items_list.controls.append(item)
            input_text.value = ""
            page.update()

    def delete_action(e):
        checked_items = [item for item in items_list.controls if item.leading.value]
        for item in checked_items:
            items_list.controls.remove(item)
        page.update()

    def save_action(e):
        saved_items = [item for item in items_list.controls if item.leading.value]
        update_data_table(saved_items)
        page.update()

    def exit_app(e):
        page.window_close()

    def toggle_checkbox(control):
        control.leading.value = not control.leading.value
        page.update()

    def update_data_table(items):
        data_table.rows.clear()
        for item in items:
            data_table.rows.append(
                ft.DataRow(
                    cells=[
                        ft.DataCell(ft.Text(item.title.value)),
                        ft.DataCell(ft.Text("是" if item.leading.value else "否")),
                    ]
                )
            )
        page.update()

    page.appbar = ft.AppBar(
        leading=ft.Row([
            ft.Text("购物清单助手1.0", size=14),
        ], alignment=ft.MainAxisAlignment.START),
        center_title=False,
        bgcolor=ft.colors.SURFACE_VARIANT,
        actions=[
            ft.IconButton(ft.icons.ADD, on_click=add_action),
            ft.IconButton(ft.icons.DELETE, on_click=delete_action),
            ft.IconButton(ft.icons.SAVE, on_click=save_action),
            ft.IconButton(ft.icons.CLOSE, on_click=exit_app),
        ],
    )

    # 包裹内容在 SafeArea 组件内
    safe_area_content = ft.SafeArea(content)

    # 添加内容到页面
    page.add(safe_area_content)

    # 初始化导航栏
    page.navigation_bar.selected_index = 0
    navigate(None)

# 启动应用
ft.app(target=main)

3. 解释说明

def add_action(e):
    if input_text.value:
        item = ft.ListTile(
            leading=ft.Checkbox(),
            title=ft.Text(input_text.value),
            on_click=lambda e: toggle_checkbox(e.control),
        )
        items_list.controls.append(item)
        input_text.value = ""
        page.update()

def delete_action(e):
    checked_items = [item for item in items_list.controls if item.leading.value]
    for item in checked_items:
        items_list.controls.remove(item)
    page.update()

def save_action(e):
    saved_items = [item for item in items_list.controls if item.leading.value]
    update_data_table(saved_items)
    page.update()

def exit_app(e):
    page.window_close()

def toggle_checkbox(control):
    control.leading.value = not control.leading.value
    page.update()

def update_data_table(items):
    data_table.rows.clear()
    for item in items:
        data_table.rows.append(
            ft.DataRow(
                cells=[
                    ft.DataCell(ft.Text(item.title.value)),
                    ft.DataCell(ft.Text("是" if item.leading.value else "否")),
                ]
            )
        )
    page.update()

add_action 函数:处理添加按钮的点击事件。
如果 input_text 的值不为空,则创建一个新的 ListTile。
leading=ft.Checkbox():在 ListTile 的左侧添加一个复选框。
title=ft.Text(input_text.value):在 ListTile 的中间显示输入的商品名称。
on_click=lambda e: toggle_checkbox(e.control):设置点击事件处理函数,用于切换复选框的状态。
将新创建的 ListTile 添加到 items_list 的 controls 列表中。
清空 input_text 的值。
调用 page.update() 更新页面。
delete_action 函数:处理删除按钮的点击事件。
使用列表推导式获取所有被勾选的 ListTile。
遍历这些被勾选的 ListTile 并从 items_list 的 controls 列表中移除它们。
调用 page.update() 更新页面。
save_action 函数:处理保存按钮的点击事件。
使用列表推导式获取所有被勾选的 ListTile。
调用 update_data_table 函数更新数据表。
调用 page.update() 更新页面。
exit_app 函数:处理退出按钮的点击事件。
关闭窗口。
toggle_checkbox 函数:处理复选框的点击事件。
切换复选框的状态。
调用 page.update() 更新页面。
update_data_table 函数:更新数据表。
清空 data_table 的所有行。
遍历所有被勾选的 ListTile,并将它们的信息添加到 data_table 中。
调用 page.update() 更新页面。

**4. 运行效果,截图为证 **

在这里插入图片描述

第十七步:更新页面函数居中显示页面内容

1.编程思路

更新页面函数,居中显示页面内容

2.示例代码


import flet as ft

def main(page: ft.Page):
    # 设置窗口大小
    page.window.width = 400
    page.window.height = 600
    # 设置窗口无边框
    page.window.frameless = True
    # 初始化内容
    content = ft.Column(
        [
            ft.Text("Body!", size=20),
        ],
        alignment=ft.MainAxisAlignment.CENTER,
        horizontal_alignment=ft.CrossAxisAlignment.CENTER,
    )

    # 输入框和列表视图
    input_text = ft.TextField(label="输入商品名称")
    items_list = ft.ListView(expand=1, spacing=10, padding=20, auto_scroll=True)
    data_table = ft.DataTable(
        columns=[
            ft.DataColumn(ft.Text("商品名称")),
            ft.DataColumn(ft.Text("是否勾选")),
        ],
        rows=[],
    )

    # 更新页面内容的函数
    def navigate(e):
        if page.navigation_bar.selected_index == 0:
            content.controls = [
                ft.Column([
                    input_text,
                    items_list,
                ], alignment=ft.MainAxisAlignment.START)
            ]
        elif page.navigation_bar.selected_index == 1:
            content.controls = [
                ft.Row(
                    [
                        ft.Column(
                            [
                                data_table,
                            ],
                            alignment=ft.MainAxisAlignment.CENTER,
                        )
                    ],
                    alignment=ft.MainAxisAlignment.CENTER,
                )
            ]
        else:
            content.controls = [
                ft.Text("关于内容!", size=20),
                ft.Divider(),
                ft.Image(src="logo传奇开心果.png", width=100, height=100),
                ft.Column([
                    ft.Text("购物清单助手移动应用app1.0", size=14),
                    ft.Text("作者:传奇开心果", size=14),
                    ft.Text("微信:lxm1093220242", size=14),
                ], alignment=ft.MainAxisAlignment.START),
            ]

        page.update()

    # 设置导航栏
    page.navigation_bar = ft.NavigationBar(
        destinations=[
            ft.NavigationBarDestination(
                icon=ft.icons.HOME, 
                selected_icon=ft.icons.HOME_ROUNDED, 
                label="主页"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.LIST, 
                selected_icon=ft.icons.LIST_ALT, 
                label="清单"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.INFO, 
                selected_icon=ft.icons.INFO_ROUNDED, 
                label="关于"
            ),
        ],
        on_change=navigate
    )

    # 设置 AppBar
    def add_action(e):
        if input_text.value:
            item = ft.ListTile(
                leading=ft.Checkbox(),
                title=ft.Text(input_text.value),
                on_click=lambda e: toggle_checkbox(e.control),
            )
            items_list.controls.append(item)
            input_text.value = ""
            page.update()

    def delete_action(e):
        checked_items = [item for item in items_list.controls if item.leading.value]
        for item in checked_items:
            items_list.controls.remove(item)
        page.update()

    def save_action(e):
        saved_items = [item for item in items_list.controls if item.leading.value]
        update_data_table(saved_items)
        page.update()

    def exit_app(e):
        page.window_close()

    def toggle_checkbox(control):
        control.leading.value = not control.leading.value
        page.update()

    def update_data_table(items):
        data_table.rows.clear()
        for item in items:
            data_table.rows.append(
                ft.DataRow(
                    cells=[
                        ft.DataCell(ft.Text(item.title.value)),
                        ft.DataCell(ft.Text("是" if item.leading.value else "否")),
                    ]
                )
            )
        page.update()

    page.appbar = ft.AppBar(
        leading=ft.Row([
            ft.Text("购物清单助手1.0", size=14),
        ], alignment=ft.MainAxisAlignment.START),
        center_title=False,
        bgcolor=ft.colors.SURFACE_VARIANT,
        actions=[
            ft.IconButton(ft.icons.ADD, on_click=add_action),
            ft.IconButton(ft.icons.DELETE, on_click=delete_action),
            ft.IconButton(ft.icons.SAVE, on_click=save_action),
            ft.IconButton(ft.icons.CLOSE, on_click=exit_app),
        ],
    )

    # 包裹内容在 SafeArea 组件内
    safe_area_content = ft.SafeArea(content)

    # 添加内容到页面
    page.add(safe_area_content)

    # 初始化导航栏
    page.navigation_bar.selected_index = 0
    navigate(None)

# 启动应用
ft.app(target=main)

3. 解释说明

更新页面内容的函数:

def navigate(e):
    if page.navigation_bar.selected_index == 0:
        content.controls = [
            ft.Column([
                input_text,
                items_list,
            ], alignment=ft.MainAxisAlignment.START)
        ]
    elif page.navigation_bar.selected_index == 1:
        content.controls = [
            ft.Row(
                [
                    ft.Column(
                        [
                            data_table,
                        ],
                        alignment=ft.MainAxisAlignment.CENTER,
                    )
                ],
                alignment=ft.MainAxisAlignment.CENTER,
            )
        ]
    else:
        content.controls = [
            ft.Text("关于内容!", size=20),
            ft.Divider(),
            ft.Image(src="logo传奇开心果.png", width=100, height=100),
            ft.Column([
                ft.Text("购物清单助手移动应用app1.0", size=14),
                ft.Text("作者:传奇开心果", size=14),
                ft.Text("微信:lxm1093220242", size=14),
            ], alignment=ft.MainAxisAlignment.START),
        ]

    page.update()

elif page.navigation_bar.selected_index == 1::当导航栏选择“清单”时,使用 ft.Row 来包裹 ft.Column,确保数据表在页面中心居中显示。
ft.Row:创建一个水平排列的容器。
alignment=ft.MainAxisAlignment.CENTER:设置 Row 的对齐方式为居中。
ft.Column:创建一个垂直排列的容器。
data_table:将数据表放入 Column 中,并确保其居中显示。

4. 运行效果,截图为证
在这里插入图片描述

第十八步:AppBar 样式修改美化

1.编程思路

AppBar 标题字体加粗, AppBar 高度调整。

2.示例代码


import flet as ft

def main(page: ft.Page):
    # 设置窗口大小和无边框
    page.window.width = 400  # 使用新的属性
    page.window.height = 600
    page.window.frameless = True
    
    # 初始化内容
    content = ft.Column(
        [
            ft.Text("Body!", size=20),
        ],
        alignment=ft.MainAxisAlignment.CENTER,
        horizontal_alignment=ft.CrossAxisAlignment.CENTER,
    )

    # 输入框和列表视图
    input_text = ft.TextField(label="输入商品名称")
    items_list = ft.ListView(expand=1, spacing=10, padding=20, auto_scroll=True)
    data_table = ft.DataTable(
        columns=[
            ft.DataColumn(ft.Text("商品名称")),
            ft.DataColumn(ft.Text("是否勾选")),
        ],
        rows=[],
    )

    # 更新页面内容的函数
    def navigate(e):
        if page.navigation_bar.selected_index == 0:
            content.controls = [
                ft.Column([
                    input_text,
                    items_list,
                ], alignment=ft.MainAxisAlignment.START)
            ]
        elif page.navigation_bar.selected_index == 1:
            content.controls = [
                ft.Row(
                    [
                        ft.Column(
                            [
                                data_table,
                            ],
                            alignment=ft.MainAxisAlignment.CENTER,
                        )
                    ],
                    alignment=ft.MainAxisAlignment.CENTER,
                )
            ]
        else:
            content.controls = [
                ft.Text("关于内容!", size=20),
                ft.Divider(),
                ft.Image(src="logo传奇开心果.png", width=100, height=100),
                ft.Column([
                    ft.Text("购物清单助手移动应用app1.0", size=14),
                    ft.Text("作者:传奇开心果", size=14),
                    ft.Text("微信:lxm1093220242", size=14),
                ], alignment=ft.MainAxisAlignment.START),
            ]

        page.update()

    # 设置导航栏
    page.navigation_bar = ft.NavigationBar(
        destinations=[
            ft.NavigationBarDestination(
                icon=ft.icons.HOME, 
                selected_icon=ft.icons.HOME_ROUNDED, 
                label="主页"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.LIST, 
                selected_icon=ft.icons.LIST_ALT, 
                label="清单"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.INFO, 
                selected_icon=ft.icons.INFO_ROUNDED, 
                label="关于"
            ),
        ],
        on_change=navigate
    )

    # 设置 AppBar
    def add_action(e):
        if input_text.value:
            item = ft.ListTile(
                leading=ft.Checkbox(),
                title=ft.Text(input_text.value),
                on_click=lambda e: toggle_checkbox(e.control),
            )
            items_list.controls.append(item)
            input_text.value = ""
            page.update()

    def delete_action(e):
        checked_items = [item for item in items_list.controls if item.leading.value]
        for item in checked_items:
            items_list.controls.remove(item)
        page.update()

    def save_action(e):
        saved_items = [item for item in items_list.controls if item.leading.value]
        update_data_table(saved_items)
        page.update()

    def exit_app(e):
        page.window_close()

    def toggle_checkbox(control):
        control.leading.value = not control.leading.value
        page.update()

    def update_data_table(items):
        data_table.rows.clear()
        for item in items:
            data_table.rows.append(
                ft.DataRow(
                    cells=[
                        ft.DataCell(ft.Text(item.title.value)),
                        ft.DataCell(ft.Text("是" if item.leading.value else "否")),
                    ]
                )
            )
        page.update()

    page.appbar = ft.AppBar(
        leading=ft.Row([
            ft.Text("购物清单助手1.0", size=14, weight=ft.FontWeight.BOLD),
        ], alignment=ft.MainAxisAlignment.START),
        center_title=False,
        bgcolor=ft.colors.SURFACE_VARIANT,
        actions=[
            ft.IconButton(ft.icons.ADD, on_click=add_action),
            ft.IconButton(ft.icons.DELETE, on_click=delete_action),
            ft.IconButton(ft.icons.SAVE, on_click=save_action),
            ft.IconButton(ft.icons.CLOSE, on_click=exit_app),
        ],
        toolbar_height=60  # 可以调整高度以适应更多的空间
    )

    # 包裹内容在 SafeArea 组件内
    safe_area_content = ft.SafeArea(content)

    # 添加内容到页面
    page.add(safe_area_content)

    # 初始化导航栏
    page.navigation_bar.selected_index = 0
    navigate(None)

# 启动应用
ft.app(target=main)

3. 解释说明

AppBar 标题字体加粗

weight=ft.FontWeight.BOLD:在 ft.Text 组件中添加了 weight 属性,使标题字体加粗。
python
leading=ft.Row([
ft.Text(“购物清单助手1.0”, size=14, weight=ft.FontWeight.BOLD),
], alignment=ft.MainAxisAlignment.START),

AppBar 高度调整

toolbar_height=60:设置了 AppBar 的高度为 60 像素,使其看起来更高一些,从而可以容纳更多的内容或留出更多的空间。
python
toolbar_height=60 # 可以调整高度以适应更多的空间

**4. 运行效果,截图为证 **
在这里插入图片描述

第十九步: 窗口大小和无边框设置使用新的属性和AppBar 标题布局优化

1.编程思路

窗口大小和无边框设置使用新的属性。AppBar 标题布局优化。

2.示例代码


import flet as ft

def main(page: ft.Page):
    # 设置窗口大小和无边框
    page.window_width = 400  # 使用新的属性
    page.window_height = 600
    page.window_frameless = True
    
    # 初始化内容
    content = ft.Column(
        [
            ft.Text("Body!", size=20),
        ],
        alignment=ft.MainAxisAlignment.CENTER,
        horizontal_alignment=ft.CrossAxisAlignment.CENTER,
    )

    # 输入框和列表视图
    input_text = ft.TextField(label="输入商品名称")
    items_list = ft.ListView(expand=1, spacing=10, padding=20, auto_scroll=True)
    data_table = ft.DataTable(
        columns=[
            ft.DataColumn(ft.Text("商品名称")),
            ft.DataColumn(ft.Text("是否勾选")),
        ],
        rows=[],
    )

    # 更新页面内容的函数
    def navigate(e):
        if page.navigation_bar.selected_index == 0:
            content.controls = [
                ft.Column([
                    input_text,
                    items_list,
                ], alignment=ft.MainAxisAlignment.START)
            ]
        elif page.navigation_bar.selected_index == 1:
            content.controls = [
                ft.Row(
                    [
                        ft.Column(
                            [
                                data_table,
                            ],
                            alignment=ft.MainAxisAlignment.CENTER,
                        )
                    ],
                    alignment=ft.MainAxisAlignment.CENTER,
                )
            ]
        else:
            content.controls = [
                ft.Text("关于内容!", size=20),
                ft.Divider(),
                ft.Image(src="logo传奇开心果.png", width=100, height=100),
                ft.Column([
                    ft.Text("购物清单助手移动应用app1.0", size=14),
                    ft.Text("作者:传奇开心果", size=14),
                    ft.Text("微信:lxm1093220242", size=14),
                ], alignment=ft.MainAxisAlignment.START),
            ]

        page.update()

    # 设置导航栏
    page.navigation_bar = ft.NavigationBar(
        destinations=[
            ft.NavigationBarDestination(
                icon=ft.icons.HOME, 
                selected_icon=ft.icons.HOME_ROUNDED, 
                label="主页"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.LIST, 
                selected_icon=ft.icons.LIST_ALT, 
                label="清单"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.INFO, 
                selected_icon=ft.icons.INFO_ROUNDED, 
                label="关于"
            ),
        ],
        on_change=navigate
    )

    # 设置 AppBar
    def add_action(e):
        if input_text.value:
            item = ft.ListTile(
                leading=ft.Checkbox(),
                title=ft.Text(input_text.value),
                on_click=lambda e: toggle_checkbox(e.control),
            )
            items_list.controls.append(item)
            input_text.value = ""
            page.update()

    def delete_action(e):
        checked_items = [item for item in items_list.controls if item.leading.value]
        for item in checked_items:
            items_list.controls.remove(item)
        page.update()

    def save_action(e):
        saved_items = [item for item in items_list.controls if item.leading.value]
        update_data_table(saved_items)
        page.update()

    def exit_app(e):
        page.window_close()

    def toggle_checkbox(control):
        control.leading.value = not control.leading.value
        page.update()

    def update_data_table(items):
        data_table.rows.clear()
        for item in items:
            data_table.rows.append(
                ft.DataRow(
                    cells=[
                        ft.DataCell(ft.Text(item.title.value)),
                        ft.DataCell(ft.Text("是" if item.leading.value else "否")),
                    ]
                )
            )
        page.update()

    page.appbar = ft.AppBar(
        leading=ft.Row(
            [
                ft.Container(
                    content=ft.Text("购物清单助手1.0", size=14, weight=ft.FontWeight.BOLD),
                    padding=ft.padding.only(left=20),  # 设置左边的 padding 为 20
                )
            ],
            alignment=ft.MainAxisAlignment.START
        ),
        center_title=False,
        bgcolor=ft.colors.SURFACE_VARIANT,
        actions=[
            ft.IconButton(ft.icons.ADD, on_click=add_action),
            ft.IconButton(ft.icons.DELETE, on_click=delete_action),
            ft.IconButton(ft.icons.SAVE, on_click=save_action),
            ft.IconButton(ft.icons.CLOSE, on_click=exit_app),
        ],
        toolbar_height=60  # 可以调整高度以适应更多的空间
    )

    # 包裹内容在 SafeArea 组件内
    safe_area_content = ft.SafeArea(content)

    # 添加内容到页面
    page.add(safe_area_content)

    # 初始化导航栏
    page.navigation_bar.selected_index = 0
    navigate(None)

# 启动应用
ft.app(target=main)

3. 解释说明

窗口大小和无边框设置

使用新的属性:

python
page.window_width = 400 # 使用新的属性
page.window_height = 600
page.window_frameless = True
这些属性的更改使得代码更简洁,并且符合 Flet 最新的 API 规范。

AppBar 标题布局优化

将 Text 组件包裹在 Container 中:

leading=ft.Row(
    [
        ft.Container(
            content=ft.Text("购物清单助手1.0", size=14, weight=ft.FontWeight.BOLD),
            padding=ft.padding.only(left=20),  # 设置左边的 padding 为 20
        )
    ],
    alignment=ft.MainAxisAlignment.START
),

这样做可以使标题更居中,并且有适当的间距,使得整个 AppBar 看起来更加整洁。

**4. 运行效果,截图为证 **
在这里插入图片描述

第二十步:清单页布局优化

1.编程思路

清单页布局优化,使得整个页面看起来更加整洁。

2.示例代码


import flet as ft

def main(page: ft.Page):
    # 设置窗口大小和无边框
    page.window_width = 400  # 使用新的属性
    page.window_height = 600
    page.window_frameless = True
    
    # 初始化内容
    content = ft.Column(
        [
            ft.Text("Body!", size=20),
        ],
        alignment=ft.MainAxisAlignment.CENTER,
        horizontal_alignment=ft.CrossAxisAlignment.CENTER,
    )

    # 输入框和列表视图
    input_text = ft.TextField(label="输入商品名称")
    items_list = ft.ListView(expand=1, spacing=10, padding=20, auto_scroll=True)
    data_table = ft.DataTable(
        columns=[
            ft.DataColumn(ft.Text("商品名称")),
            ft.DataColumn(ft.Text("是否勾选")),
        ],
        rows=[],
    )

    # 更新页面内容的函数
    def navigate(e):
        if page.navigation_bar.selected_index == 0:
            content.controls = [
                ft.Column([
                    input_text,
                    items_list,
                ], alignment=ft.MainAxisAlignment.START)
            ]
        elif page.navigation_bar.selected_index == 1:
            content.controls = [
                ft.Column(
                    [
                        ft.Text("购物清单", size=18, weight=ft.FontWeight.BOLD, text_align=ft.TextAlign.CENTER),
                        ft.Container(
                            content=ft.Column(
                                [
                                    data_table,
                                ],
                                alignment=ft.MainAxisAlignment.CENTER,
                                horizontal_alignment=ft.CrossAxisAlignment.CENTER
                            ),
                            padding=20,
                            alignment=ft.alignment.center
                        ),
                    ],
                    alignment=ft.MainAxisAlignment.CENTER,
                    horizontal_alignment=ft.CrossAxisAlignment.CENTER
                )
            ]
        else:
            content.controls = [
                ft.Text("关于内容!", size=20),
                ft.Divider(),
                ft.Image(src="logo传奇开心果.png", width=100, height=100),
                ft.Column([
                    ft.Text("购物清单助手移动应用app1.0", size=14),
                    ft.Text("作者:传奇开心果", size=14),
                    ft.Text("微信:lxm1093220242", size=14),
                ], alignment=ft.MainAxisAlignment.START),
            ]

        page.update()

    # 设置导航栏
    page.navigation_bar = ft.NavigationBar(
        destinations=[
            ft.NavigationBarDestination(
                icon=ft.icons.HOME, 
                selected_icon=ft.icons.HOME_ROUNDED, 
                label="主页"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.LIST, 
                selected_icon=ft.icons.LIST_ALT, 
                label="清单"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.INFO, 
                selected_icon=ft.icons.INFO_ROUNDED, 
                label="关于"
            ),
        ],
        on_change=navigate
    )

    # 设置 AppBar
    def add_action(e):
        if input_text.value:
            item = ft.ListTile(
                leading=ft.Checkbox(),
                title=ft.Text(input_text.value),
                on_click=lambda e: toggle_checkbox(e.control),
            )
            items_list.controls.append(item)
            input_text.value = ""
            page.update()

    def delete_action(e):
        checked_items = [item for item in items_list.controls if item.leading.value]
        for item in checked_items:
            items_list.controls.remove(item)
        page.update()

    def save_action(e):
        saved_items = [item for item in items_list.controls if item.leading.value]
        update_data_table(saved_items)
        page.update()

    def exit_app(e):
        page.window_close()

    def toggle_checkbox(control):
        control.leading.value = not control.leading.value
        page.update()

    def update_data_table(items):
        data_table.rows.clear()
        for item in items:
            data_table.rows.append(
                ft.DataRow(
                    cells=[
                        ft.DataCell(ft.Text(item.title.value)),
                        ft.DataCell(ft.Text("是" if item.leading.value else "否")),
                    ]
                )
            )
        page.update()

    page.appbar = ft.AppBar(
        leading=ft.Row(
            [
                ft.Container(
                    content=ft.Text("购物清单助手1.0", size=14, weight=ft.FontWeight.BOLD),
                    padding=ft.padding.only(left=20),  # 设置左边的 padding 为 20
                )
            ],
            alignment=ft.MainAxisAlignment.START
        ),
        center_title=False,
        bgcolor=ft.colors.SURFACE_VARIANT,
        actions=[
            ft.IconButton(ft.icons.ADD, on_click=add_action),
            ft.IconButton(ft.icons.DELETE, on_click=delete_action),
            ft.IconButton(ft.icons.SAVE, on_click=save_action),
            ft.IconButton(ft.icons.CLOSE, on_click=exit_app),
        ],
        toolbar_height=60  # 可以调整高度以适应更多的空间
    )

    # 包裹内容在 SafeArea 组件内
    safe_area_content = ft.SafeArea(content)

    # 添加内容到页面
    page.add(safe_area_content)

    # 初始化导航栏
    page.navigation_bar.selected_index = 0
    navigate(None)

# 启动应用
ft.app(target=main)

3. 解释说明

*** “清单”页面的布局优化***

添加带有 padding 的 Container:

elif page.navigation_bar.selected_index == 1:
    content.controls = [
        ft.Column(
            [
                ft.Text("购物清单", size=18, weight=ft.FontWeight.BOLD, text_align=ft.TextAlign.CENTER),
                ft.Container(
                    content=ft.Column(
                        [
                            data_table,
                        ],
                        alignment=ft.MainAxisAlignment.CENTER,
                        horizontal_alignment=ft.CrossAxisAlignment.CENTER
                    ),
                    padding=20,
                    alignment=ft.alignment.center
                ),
            ],
            alignment=ft.MainAxisAlignment.CENTER,
            horizontal_alignment=ft.CrossAxisAlignment.CENTER
        )
    ]

这样做可以使 data_table 更加居中,并且有适当的间距,使得整个页面看起来更加整洁。

其他部分保持不变

**4. 运行效果,截图为证 **

在这里插入图片描述

第二十一步:设置列表视图的高度设置滚动条根据内容自动开启

1.编程思路

设置列表视图的高度动态计算列表视图的高度。设置滚动条根据内容自动显现。

2.示例代码


import flet as ft

def main(page: ft.Page):
    # 设置窗口大小和无边框
    page.window_width = 400
    page.window_height = 600
    page.window_frameless = True

    # 初始化内容
    content = ft.Column(
        [
            ft.Text("Body!", size=20),
        ],
        alignment=ft.MainAxisAlignment.CENTER,
        horizontal_alignment=ft.CrossAxisAlignment.CENTER,
    )

    # 输入框和列表视图
    input_text = ft.TextField(label="输入商品名称")
    items_list = ft.ListView(expand=1, spacing=10, padding=20, auto_scroll=True)

    data_table = ft.DataTable(
        columns=[
            ft.DataColumn(ft.Text("商品名称")),
            ft.DataColumn(ft.Text("是否勾选")),
        ],
        rows=[],
    )

    # 更新页面内容的函数
    def navigate(e):
        if page.navigation_bar.selected_index == 0:
            content.controls = [
                ft.Column([
                    input_text,
                    ft.Column(
                        [items_list],
                        height=page.window_height - 120,  # 减去导航栏和输入框的高度
                        scroll=ft.ScrollMode.AUTO
                    ),
                ], alignment=ft.MainAxisAlignment.START)
            ]
        elif page.navigation_bar.selected_index == 1:
            content.controls = [
                ft.Column(
                    [
                        ft.Text("购物清单", size=18, weight=ft.FontWeight.BOLD, text_align=ft.TextAlign.CENTER),
                        ft.Container(
                            content=ft.Column(
                                [
                                    data_table,
                                ],
                                alignment=ft.MainAxisAlignment.CENTER,
                                horizontal_alignment=ft.CrossAxisAlignment.CENTER
                            ),
                            padding=20,
                            alignment=ft.alignment.center
                        ),
                    ],
                    alignment=ft.MainAxisAlignment.CENTER,
                    horizontal_alignment=ft.CrossAxisAlignment.CENTER
                )
            ]
        else:
            content.controls = [
                ft.Text("关于内容!", size=20),
                ft.Divider(),
                ft.Image(src="logo传奇开心果.png", width=100, height=100),
                ft.Column([
                    ft.Text("购物清单助手移动应用app1.0", size=14),
                    ft.Text("作者:传奇开心果", size=14),
                    ft.Text("微信:lxm1093220242", size=14),
                ], alignment=ft.MainAxisAlignment.START),
            ]

        page.update()

    # 设置导航栏
    page.navigation_bar = ft.NavigationBar(
        destinations=[
            ft.NavigationBarDestination(
                icon=ft.icons.HOME, 
                selected_icon=ft.icons.HOME_ROUNDED, 
                label="主页"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.LIST, 
                selected_icon=ft.icons.LIST_ALT, 
                label="清单"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.INFO, 
                selected_icon=ft.icons.INFO_ROUNDED, 
                label="关于"
            ),
        ],
        on_change=navigate
    )

    # 设置 AppBar
    def add_action(e):
        if input_text.value:
            item = ft.ListTile(
                leading=ft.Checkbox(),
                title=ft.Text(input_text.value),
                on_click=lambda e: toggle_checkbox(e.control),
            )
            items_list.controls.append(item)
            input_text.value = ""
            page.update()

    def delete_action(e):
        checked_items = [item for item in items_list.controls if item.leading.value]
        for item in checked_items:
            items_list.controls.remove(item)
        page.update()

    def save_action(e):
        saved_items = [item for item in items_list.controls if item.leading.value]
        update_data_table(saved_items)
        page.update()

    def exit_app(e):
        page.window_close()

    def toggle_checkbox(control):
        control.leading.value = not control.leading.value
        page.update()

    def update_data_table(items):
        data_table.rows.clear()
        for item in items:
            data_table.rows.append(
                ft.DataRow(
                    cells=[
                        ft.DataCell(ft.Text(item.title.value)),
                        ft.DataCell(ft.Text("是" if item.leading.value else "否")),
                    ]
                )
            )
        page.update()

    page.appbar = ft.AppBar(
        leading=ft.Row(
            [
                ft.Container(
                    content=ft.Text("购物清单助手1.0", size=14, weight=ft.FontWeight.BOLD),
                    padding=ft.padding.only(left=20),  # 设置左边的 padding 为 20
                )
            ],
            alignment=ft.MainAxisAlignment.START
        ),
        center_title=False,
        bgcolor=ft.colors.SURFACE_VARIANT,
        actions=[
            ft.IconButton(ft.icons.ADD, on_click=add_action),
            ft.IconButton(ft.icons.DELETE, on_click=delete_action),
            ft.IconButton(ft.icons.SAVE, on_click=save_action),
            ft.IconButton(ft.icons.CLOSE, on_click=exit_app),
        ],
        toolbar_height=60  # 可以调整高度以适应更多的空间
    )

    # 包裹内容在 SafeArea 组件内
    safe_area_content = ft.SafeArea(content)

    # 添加内容到页面
    page.add(safe_area_content)

    # 初始化导航栏
    page.navigation_bar.selected_index = 0
    navigate(None)

# 启动应用
ft.app(target=main)

3. 解释说明

列表视图的高度设置:

动态计算列表视图的高度,减去导航栏和输入框的高度。

ft.Column(
                        [items_list],
                        height=page.window_height - 120,  # 减去导航栏和输入框的高度
                        scroll=ft.ScrollMode.AUTO
                    ),

设置主页列表视图自动开启滚动条

items_list = ft.ListView(expand=1, spacing=10, padding=20, auto_scroll=True)

 scroll=ft.ScrollMode.AUTO

优化了代码结构,使其更简洁易读。

**4. 运行效果,截图为证 **
在这里插入图片描述

第二十二步、优化设置:主页列表视图高度和清单页数据表组件高度

1.编程思路

优化设置:主页列表视图高度和清单页数据表组件高度,进一步优化样式设置,使达到和谐美观。

2.示例代码


import flet as ft

def main(page: ft.Page):
    # 设置窗口大小和无边框
    page.window_width = 400
    page.window_height = 600
    page.window_frameless = True

    # 初始化内容
    content = ft.Column(
        [
            ft.Text("Body!", size=20),
        ],
        alignment=ft.MainAxisAlignment.CENTER,
        horizontal_alignment=ft.CrossAxisAlignment.CENTER,
    )

    # 输入框和列表视图
    input_text = ft.TextField(label="输入商品名称")
    items_list = ft.ListView(expand=1, spacing=10, padding=20, auto_scroll=True)

    data_table = ft.DataTable(
        columns=[
            ft.DataColumn(ft.Text("商品名称")),
            ft.DataColumn(ft.Text("是否勾选")),
        ],
        rows=[],
    )

    # 更新页面内容的函数
    def navigate(e):
        if page.navigation_bar.selected_index == 0:
            content.controls = [
                ft.Column([
                    input_text,
                    ft.Column(
                        [items_list],
                        height=page.window_height - 220,  # 减去导航栏和输入框的高度
                        scroll=ft.ScrollMode.AUTO
                    ),
                ], alignment=ft.MainAxisAlignment.START)
            ]
        elif page.navigation_bar.selected_index == 1:
            content.controls = [
                ft.Column(
                    [
                        ft.Text("购物清单", size=18, weight=ft.FontWeight.BOLD, text_align=ft.TextAlign.CENTER),
                        ft.Container(
                            content=ft.Column(
                                [
                                    ft.Column(
                                        [data_table],
                                        height=page.window_height - 220,  # 减去导航栏和标题的高度
                                        scroll=ft.ScrollMode.AUTO
                                    ),
                                ],
                                alignment=ft.MainAxisAlignment.CENTER,
                                horizontal_alignment=ft.CrossAxisAlignment.CENTER
                            ),
                            padding=20,
                            alignment=ft.alignment.center
                        ),
                    ],
                    alignment=ft.MainAxisAlignment.CENTER,
                    horizontal_alignment=ft.CrossAxisAlignment.CENTER
                )
            ]
        else:
            content.controls = [
                ft.Text("关于内容!", size=20),
                ft.Divider(),
                ft.Image(src="logo传奇开心果.png", width=100, height=100),
                ft.Column([
                    ft.Text("购物清单助手移动应用app1.0", size=14),
                    ft.Text("作者:传奇开心果", size=14),
                    ft.Text("微信:lxm1093220242", size=14),
                ], alignment=ft.MainAxisAlignment.START),
            ]

        page.update()

    # 设置导航栏
    page.navigation_bar = ft.NavigationBar(
        destinations=[
            ft.NavigationBarDestination(
                icon=ft.icons.HOME, 
                selected_icon=ft.icons.HOME_ROUNDED, 
                label="主页"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.LIST, 
                selected_icon=ft.icons.LIST_ALT, 
                label="清单"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.INFO, 
                selected_icon=ft.icons.INFO_ROUNDED, 
                label="关于"
            ),
        ],
        on_change=navigate
    )

    # 设置 AppBar
    def add_action(e):
        if input_text.value:
            item = ft.ListTile(
                leading=ft.Checkbox(),
                title=ft.Text(input_text.value),
                on_click=lambda e: toggle_checkbox(e.control),
            )
            items_list.controls.append(item)
            input_text.value = ""
            page.update()

    def delete_action(e):
        checked_items = [item for item in items_list.controls if item.leading.value]
        for item in checked_items:
            items_list.controls.remove(item)
        page.update()

    def save_action(e):
        saved_items = [item for item in items_list.controls if item.leading.value]
        update_data_table(saved_items)
        page.update()

    def exit_app(e):
        page.window_close()

    def toggle_checkbox(control):
        control.leading.value = not control.leading.value
        page.update()

    def update_data_table(items):
        data_table.rows.clear()
        for item in items:
            data_table.rows.append(
                ft.DataRow(
                    cells=[
                        ft.DataCell(ft.Text(item.title.value)),
                        ft.DataCell(ft.Text("是" if item.leading.value else "否")),
                    ]
                )
            )
        page.update()

    page.appbar = ft.AppBar(
        leading=ft.Row(
            [
                ft.Container(
                    content=ft.Text("购物清单助手1.0", size=14, weight=ft.FontWeight.BOLD),
                    padding=ft.padding.only(left=20),  # 设置左边的 padding 为 20
                )
            ],
            alignment=ft.MainAxisAlignment.START
        ),
        center_title=False,
        bgcolor=ft.colors.SURFACE_VARIANT,
        actions=[
            ft.IconButton(ft.icons.ADD, on_click=add_action),
            ft.IconButton(ft.icons.DELETE, on_click=delete_action),
            ft.IconButton(ft.icons.SAVE, on_click=save_action),
            ft.IconButton(ft.icons.CLOSE, on_click=exit_app),
        ],
        toolbar_height=60  # 可以调整高度以适应更多的空间
    )

    # 包裹内容在 SafeArea 组件内
    safe_area_content = ft.SafeArea(content)

    # 添加内容到页面
    page.add(safe_area_content)

    # 初始化导航栏
    page.navigation_bar.selected_index = 0
    navigate(None)

# 启动应用
ft.app(target=main)

3. 解释说明

主页列表视图高度尺寸优化设置

ft.Column(
                        [items_list],
                        height=page.window_height - 220,  # 减去导航栏和输入框的高度
                        scroll=ft.ScrollMode.AUTO
                    ),

清单页数据表组件高度尺寸设置优化

ft.Column(
                                        [data_table],
                                        height=page.window_height - 220,  # 减去导航栏和标题的高度
                                        scroll=ft.ScrollMode.AUTO
                                    ),

**4. 运行效果,截图为证 **
在这里插入图片描述

在这里插入图片描述

二十三、使用json文件永久存储数据完整示例源代码

1.编程思路:

使用json文件,永久存储数据。完整示例源代码。完成任务,收工。

2.完整示例源代码:

import flet as ft
import json
import os

# 定义数据模型
class Item:
    def __init__(self, name, checked=False):
        self.name = name
        self.checked = checked

    def to_dict(self):
        return {'name': self.name, 'checked': self.checked}

    @classmethod
    def from_dict(cls, data):
        return cls(data['name'], data['checked'])

# 数据文件路径
DATA_FILE = 'data.json'

# 读取数据
def load_data():
    if os.path.exists(DATA_FILE):
        with open(DATA_FILE, 'r') as file:
            data = json.load(file)
            return [Item.from_dict(item) for item in data]
    return []

# 保存数据
def save_data(items):
    data = [item.to_dict() for item in items]
    with open(DATA_FILE, 'w') as file:
        json.dump(data, file, indent=2)

# 初始化内容
content = ft.Column(
    [
        ft.Text("Body!", size=20),
    ],
    alignment=ft.MainAxisAlignment.CENTER,
    horizontal_alignment=ft.CrossAxisAlignment.CENTER,
)

# 输入框和列表视图
input_text = ft.TextField(label="输入商品名称")
items_list = ft.ListView(expand=1, spacing=10, padding=20, auto_scroll=True)

data_table = ft.DataTable(
    columns=[
        ft.DataColumn(ft.Text("商品名称")),
        ft.DataColumn(ft.Text("是否勾选")),
    ],
    rows=[],
)

# 设置导航栏
def main(page: ft.Page):
    global items  # 将 items 定义为全局变量
    items = load_data()  # 初始化 items

    page.window.width = 400
    page.window.height = 600
    page.window.frameless = True

    # 更新页面内容的函数
    def navigate(e):
        if page.navigation_bar.selected_index == 0:
            content.controls = [
                ft.Column([
                    input_text,
                    ft.Column(
                        [items_list],
                        height=page.window.height - 220,  # 减去导航栏和输入框的高度
                        scroll=ft.ScrollMode.AUTO
                    ),
                ], alignment=ft.MainAxisAlignment.START)
            ]
        elif page.navigation_bar.selected_index == 1:
            content.controls = [
                ft.Column(
                    [
                        ft.Text("购物清单", size=18, weight=ft.FontWeight.BOLD, text_align=ft.TextAlign.CENTER),
                        ft.Container(
                            content=ft.Column(
                                [
                                    ft.Column(
                                        [data_table],
                                        height=page.window.height - 220,  # 减去导航栏和标题的高度
                                        scroll=ft.ScrollMode.AUTO
                                    ),
                                ],
                                alignment=ft.MainAxisAlignment.CENTER,
                                horizontal_alignment=ft.CrossAxisAlignment.CENTER
                            ),
                            padding=20,
                            alignment=ft.alignment.center
                        ),
                    ],
                    alignment=ft.MainAxisAlignment.CENTER,
                    horizontal_alignment=ft.CrossAxisAlignment.CENTER
                )
            ]
        else:
            content.controls = [
                ft.Text("关于内容!", size=20),
                ft.Divider(),
                ft.Image(src="logo传奇开心果.png", width=100, height=100),
                ft.Column([
                    ft.Text("购物清单助手移动应用app1.0", size=14),
                    ft.Text("作者:传奇开心果", size=14),
                    ft.Text("微信:lxm1093220242", size=14),
                ], alignment=ft.MainAxisAlignment.START),
            ]

        page.update()

    # 设置导航栏
    page.navigation_bar = ft.NavigationBar(
        destinations=[
            ft.NavigationBarDestination(
                icon=ft.icons.HOME, 
                selected_icon=ft.icons.HOME_ROUNDED, 
                label="主页"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.LIST, 
                selected_icon=ft.icons.LIST_ALT, 
                label="清单"
            ),
            ft.NavigationBarDestination(
                icon=ft.icons.INFO, 
                selected_icon=ft.icons.INFO_ROUNDED, 
                label="关于"
            ),
        ],
        on_change=navigate
    )

    # 设置 AppBar
    page.appbar = ft.AppBar(
        leading=ft.Row(
            [
                ft.Container(
                    content=ft.Text("购物清单助手1.0", size=14, weight=ft.FontWeight.BOLD),
                    padding=ft.padding.only(left=20),  # 设置左边的 padding 为 20
                )
            ],
            alignment=ft.MainAxisAlignment.START
        ),
        center_title=False,
        bgcolor=ft.colors.SURFACE_VARIANT,
        actions=[
            ft.IconButton(ft.icons.ADD, on_click=lambda e: add_action(e, page)),
            ft.IconButton(ft.icons.DELETE, on_click=lambda e: delete_action(e, page)),
            ft.IconButton(ft.icons.SAVE, on_click=lambda e: save_action(e, page)),
            ft.IconButton(ft.icons.CLOSE, on_click=lambda e: exit_app(e, page)),
        ],
        toolbar_height=60  # 可以调整高度以适应更多的空间
    )

    # 初始化数据表
    for item in items:
        items_list.controls.append(
            ft.ListTile(
                leading=ft.Checkbox(value=item.checked, on_change=lambda e, i=item: toggle_checkbox(e, page, i)),
                title=ft.Text(item.name),
            )
        )
        data_table.rows.append(
            ft.DataRow(
                cells=[
                    ft.DataCell(ft.Text(item.name)),
                    ft.DataCell(ft.Text("是" if item.checked else "否")),
                ]
            )
        )

    # 包裹内容在 SafeArea 组件内
    safe_area_content = ft.SafeArea(content)

    # 添加内容到页面
    page.add(safe_area_content)

    # 初始化导航栏
    page.navigation_bar.selected_index = 0
    navigate(None)

# 添加新商品
def add_action(e, page):
    if input_text.value:
        item = Item(input_text.value)
        items.append(item)
        items_list.controls.append(
            ft.ListTile(
                leading=ft.Checkbox(value=item.checked, on_change=lambda e, i=item: toggle_checkbox(e, page, i)),
                title=ft.Text(item.name),
            )
        )
        data_table.rows.append(
            ft.DataRow(
                cells=[
                    ft.DataCell(ft.Text(item.name)),
                    ft.DataCell(ft.Text("是" if item.checked else "否")),
                ]
            )
        )
        input_text.value = ""
        save_data(items)
        page.update()

# 删除已选择的商品
def delete_action(e, page):
    checked_items = [item for item in items if item.checked]
    for item in checked_items:
        index = items.index(item)
        items_list.controls.pop(index)
        data_table.rows.pop(index)
        items.remove(item)
    save_data(items)
    page.update()

# 保存数据
def save_action(e, page):
    save_data(items)
    page.update()

# 退出应用
def exit_app(e, page):
    page.window_close()

# 切换商品状态
def toggle_checkbox(e, page, item):
    index = items.index(item)
    item.checked = e.control.value
    data_table.rows[index].cells[1].content.value = "是" if item.checked else "否"
    save_data(items)
    page.update()

# 启动应用
ft.app(target=main)

3.解释

这段代码实现了一个基于Flet框架的简单购物清单手机应用app,具有以下功能:

数据模型:

定义了Item类用于表示购物清单中的每一条目,并提供了序列化和反序列化的功能。

数据持久化:

通过JSON文件读取和保存购物清单的数据。

用户界面:

包含一个导航栏,支持切换到“主页”、“清单”和“关于”三个页面。
主页显示一个输入框用于添加新的商品条目以及一个列表展示所有条目。
清单页面则用表格形式展示了所有的商品及其是否被勾选的状态。
关于页面展示了应用的相关信息。

功能按钮:

添加按钮:允许用户输入新的商品并将其添加到清单中。
删除按钮:移除所有被勾选的商品。
保存按钮:将当前状态保存到文件。
退出按钮:关闭应用程序。

总结:

该应用充分利用了Flet库提供的组件来构建响应式的用户界面,并且通过简单的事件处理机制实现了与用户的交互。此外,它还支持数据的持久化存储,确保即使在程序关闭后也能保留用户的数据。

第二十四、整体编程思路和结构

这个程序是一个购物清单助手应用,使用了 Flet 库来创建界面。以下是程序的主要编程思路和结构的介绍:

1. 数据模型

  • Item类: 代表购物清单中的一项商品,包含商品名称和是否勾选的状态。提供了两个方法:
    • to_dict(): 将 Item 实例转换为字典,方便 JSON 序列化。
    • from_dict(data): 从字典创建 Item 实例,方便 JSON 反序列化。

2. 数据的读写

  • load_data(): 读取 JSON 文件中的购物清单数据,返回 Item 对象的列表。如果文件不存在,则返回空列表。
  • save_data(items): 将 Item 对象列表保存到 JSON 文件中,以便持久化存储购物清单。

3. 界面设计

  • content: 定义主内容区域,初始时显示一个简单的文本。
  • input_text: 输入框,让用户输入新商品名称。
  • items_list: 列表视图,展示所有商品。
  • data_table: 数据表形式展示购物清单,包含商品名称和是否勾选的状态。

4. 主函数 main

  • 初始化页面: 设置窗口大小和无边框样式。
  • 导航栏: 包含三个选项卡(主页、清单、关于),根据选中的选项卡更新显示内容。
  • AppBar: 包含标题和操作按钮(添加、删除、保存、关闭)。

5. 功能实现

  • 添加商品(add_action): 从输入框获取商品名称,创建新的 Item 实例,并更新列表和数据表。
  • 删除商品(delete_action): 识别已经勾选的商品列表,删除相应的条目,并更新数据。
  • 保存数据(save_action): 调用 save_data 函数,保存当前的购物清单。
  • 退出应用(exit_app): 关闭应用窗口。
  • 切换状态(toggle_checkbox): 当勾选框状态改变时,更新相应商品的状态,并同步更新数据表。

6. 启动应用

最后,通过 Flet 的 app 方法启动应用,指定 main 作为主函数。

总结

这个购物清单应用展示了如何使用 Flet 构建一个简单的用户界面,同时支持基本的数据持久化和交互功能。整体设计考虑了代码的可读性和功能的扩展性,使得未来添加新特性时可以简单地修改或扩展现有代码。
在这里插入图片描述

在这里插入图片描述

评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

传奇开心果编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值