万万哇 发表于 2024-10-20 04:04:04

【易上手快捷开发新框架技术】Flet购物清单助手桌面版分步调示例、自主创新

媒介

实现360桌面程序那样酷炫的界面,变异奇异的造型,是我很早以前的空想,也可以说是夙愿了。试了很多UI框架,都不尽人意,大概是自定义能力有限,大概是自定义难度较大,机动性不足。对我来说,可以说夙愿难了,最近发现了Flet框架,听介绍说控件自定义和控件组合能力特别强,还简单高效,漂亮时尚。我大胆试水,果然是如许,几天时间就如愿以偿,圆了少年空想。以前,说起Python语言,做做后端开发还可以,Pythongui做成的UI界面基本就是土气,丑陋不堪。Flet框架的出现石破天惊,改变了这个局面,因为它继续了flutter时尚漂亮的基因,无处不在的丝滑灵动的动画,眇小调和心旷神怡的色差调色,漂亮雅观的当代元素的组件比比皆是,信手拈来,都是专业级别的。语法继续了Python语言的贴近自然语言特性,不限于此,还做了大量组件封装,写代码和语法明白简单明了,高效快捷,轻易上手,对初学者很友爱。自适应和响应式结构,跨平台跨端都显示出了很好的适应性。一登场,一个华丽的亮相,就让人瞠目结舌,惊掉了眼镜。作为一个诞生才两年的UI框架,目前,还不尽人意的是打包安卓iOS手机应用必须拥有高速稳固的网络,平常网络乐成率低。更大的痛点是继续了flutter依靠配置繁琐复杂,报错频繁,让人不胜其烦。写代码记事本都能写,显然不怎么依靠IDE,很知心又舒心。但说起打包部署来,我不得不吐槽。就一个环境配置,Android studio要安装,VSstudio要安装,JDK要安装,AndroidSDK要安装,flutter要安装,grade要安装,都是重装备。小马拉大车那叫个费劲,满眼都是任性和尴尬!Flet开发是轻盈快捷,打包部署就是大雨天泥泞路上人抗马拉重装备,行军路上那叫个艰巨!爱恨情仇,就都是她了!情未了,一波未平,一波又起,Flet框架为Python语言前端开发涂写了浓墨重彩的一笔。不容置疑,她的诞生,使Python成为了前端开发一道靓丽的风景线。
一、利用tabs组件搭建桌面程序雏形框架,正宗、规范开局

1.编程思路
创建新页面,添加tabs组件,利用tabs组件实现单击标签切换内容页面。
2.示例代码:
import flet as ft

def main(page: ft.Page):

    t = ft.Tabs(
      selected_index=1,
      animation_duration=300,
      tabs=[
            ft.Tab(
                text="Tab 1",
                content=ft.Container(
                  content=ft.Text("这是 Tab 1"), alignment=ft.alignment.center
                ),
            ),
            ft.Tab(
                tab_content=ft.Icon(ft.icons.SEARCH),
                content=ft.Text("这是 Tab 2"),
            ),
            ft.Tab(
                text="Tab 3",
                icon=ft.icons.SETTINGS,
                content=ft.Text("这是 Tab 3"),
            ),
      ],
      expand=1,
    )

    page.add(t)

ft.app(target=main)
3.表明说明:
拿来主义,直接利用官方教程tabs组件源代码,创建购物清单助手桌面版程序窗口界面雏形框架。就从利用经典范例代码开始,正宗、规范开局。
4. 运行结果,截图为证
https://i-blog.csdnimg.cn/direct/ebed0b8807fa41079774be57fb26f343.png#pic_center
二、自主创新自定义选项卡组件CustomTab实现本身多年夙愿和时尚追求的界面设计

1.编程思路:
官方tabs组件不符合项目要求,为了拥有本身设想的选项卡特性,在Flet微信交流群网友的启迪和鼓励下,积极探索探究,苦心钻研,利用Flet组合控件的方式自主创新自定义选项卡控件CustomTab,开源发布,实现心中夙愿。这是本程序开发一大亮点,也为Flet生态和开源作出本身的贡献。以萤火虫微弱的光亮,在茫茫黑夜,为探索者脚下和眼前点亮一盏小桔灯。
2.示例代码:
示例代码如下:
import flet as ft

class CustomTab:
    def __init__(self, text, icon_path, on_click=None):
      self.text = text
      self.icon_path = icon_path
      self.on_click = on_click

    def build(self):
      # 创建显示图标的行
      image_row = ft.Row(
            ,
            alignment=ft.MainAxisAlignment.CENTER
      )
      # 创建显示文本的行
      text_row = ft.Row(
            ,
            alignment=ft.MainAxisAlignment.CENTER
      )
      # 创建包含图标和文本的列
      container = ft.Column(
            ,
            alignment=ft.MainAxisAlignment.CENTER,
            horizontal_alignment=ft.CrossAxisAlignment.CENTER,
            spacing=5
      )
      return ft.Container(
            content=container,
            bgcolor=ft.colors.GREEN_500,
            height=128,
            width=128,
            border_radius=8,
            on_click=self.on_click
      )

def main(page: ft.Page):
    current_tab = None
    content_container = ft.Column()# 用于显示页面内容的容器

    # 定义每个标签对应的内容
    tab_contents = {
      "我的通讯": ft.Text("这是我的通讯页面", bgcolor=ft.colors.RED),
      "网络收藏": ft.Text("这是网络收藏页面", bgcolor=ft.colors.ORANGE),
      "电脑清理": ft.Text("这是电脑清理页面", bgcolor=ft.colors.GREEN),
      "系统修复": ft.Text("这是系统修复页面", bgcolor=ft.colors.BLUE),
      "我的笔记": ft.Text("这是我的笔记页面", bgcolor=ft.colors.PURPLE),
      "功能大全": ft.Text("这是功能大全页面", bgcolor=ft.colors.YELLOW),
    }

    def tab_clicked(e):
      nonlocal current_tab
      tab_text = e.control.content.controls.controls.value# 获取被点击的标签文本
      print(f"{tab_text} tab clicked")

      # 更新当前标签的背景颜色
      if current_tab:
            current_tab.bgcolor = ft.colors.GREEN_500
      current_tab = e.control
      current_tab.bgcolor = ft.colors.GREEN_700
      page.update()

      # 更新内容容器中的内容
      content_container.clean()# 清空旧内容
      content_container.controls.append(tab_contents.get(tab_text, ft.Text("未知页面")))
      page.update()

    # 创建并添加所有标签
    tabs = ft.Row(
      [
            CustomTab(text="我的通讯", icon_path="aa.png", on_click=tab_clicked).build(),
            CustomTab(text="网络收藏", icon_path="bb.png", on_click=tab_clicked).build(),
            CustomTab(text="电脑清理", icon_path="cc.png", on_click=tab_clicked).build(),
            CustomTab(text="系统修复", icon_path="dd.png", on_click=tab_clicked).build(),
            CustomTab(text="我的笔记", icon_path="ee.png", on_click=tab_clicked).build(),
            CustomTab(text="功能大全", icon_path="ff.png", on_click=tab_clicked).build(),
      ],
      alignment=ft.MainAxisAlignment.START
    )

    page.add(tabs, content_container)# 添加标签和内容容器到页面

ft.app(target=main)
3. 表明说明:
“雄关漫道真如铁,而今迈步从头越。从头越,苍山如海,残阳多血。”引用毛主席的诗歌抒怀,开始下面的示例代码表明说明。
上述Python代码利用了Flet库来创建一个具有自定义标签栏的应用程序。以下是该代码的主要功能和组成部门的概述:
CustomTab类:这是一个自定义类,用于创建带有图标和文本的标签。每个标签都有独特的自定义样式,自定义图标和文本,每个标签可以指定文本、图标路径以及可选的点击事件处理函数。并且在自定义标签被选中时会改变样式以指示其活动状态。
main函数:这是应用程序的主入口点,定义了页面结构和交互逻辑。
初始化变量current_tab用于跟踪当前选中的标签。
content_container是一个Column控件,用于动态展示差别标签对应的内容。
定义了一个字典tab_contents,此中键是标签的文本,值是与这些标签关联的内容组件。
tab_clicked函数处理标签被点击时的行为,包括更新当前标签的状态(背景颜色)和更新内容容器以显示新的内容。
创建了一个包罗多个CustomTab实例的水平结构Row,这些实例分别代表差别的标签,并且为每个标签指定了点击事件处理器。
末了将标签栏和内容容器添加到页面上,并通过ft.app(target=main)启动应用程序。
团体来看,这段代码实现了一个新奇漂亮的标签切换界面,用户可以通过点击雅观漂亮的标签来欣赏差别的内容区域。每个标签都有独特的自定义样式,自定义图标和文本,并且在被选中时会改变样式以指示其活动状态。
“黄洋界上炮声隆,报道敌军宵遁。”以毛主席的另外两句诗抒怀结束这一段讲授。
4. 运行结果,截图为证
https://img-blog.csdnimg.cn/54e12661343544bba56ac147e2731014.png
三、修改标签被选中时会改变样式以指示其活动状态,打造升级版自定义选项卡组件customtab Pro

1.编程思路:
未选中图标背景为light green,选中背景变为light yellow,通过标签被选中时会改变样式以指示其活动状态。初始为:未选中。
2.示例代码:
示例代码如下:
import flet as ft

class CustomTab:
    def __init__(self, text, icon_path, on_click=None):
      self.text = text
      self.icon_path = icon_path
      self.on_click = on_click
      self.bgcolor = ft.colors.LIGHT_GREEN# 设置初始背景色为亮绿色

    def build(self):
      # 创建显示图标的行
      image_row = ft.Row(
            ,
            alignment=ft.MainAxisAlignment.CENTER
      )
      # 创建显示文本的行
      text_row = ft.Row(
            ,
            alignment=ft.MainAxisAlignment.CENTER
      )
      # 创建包含图标和文本的列
      container = ft.Column(
            ,
            alignment=ft.MainAxisAlignment.CENTER,
            horizontal_alignment=ft.CrossAxisAlignment.CENTER,
            spacing=5
      )
      return ft.Container(
            content=container,
            bgcolor=self.bgcolor,# 使用类变量来设置背景色
            height=128,
            width=128,
            border_radius=8,
            on_click=self.on_click
      )

def main(page: ft.Page):
    current_tab = None
    content_container = ft.Column()# 用于显示页面内容的容器

    # 定义每个标签对应的内容
    tab_contents = {
      "我的通讯": ft.Text("这是我的通讯页面", bgcolor=ft.colors.RED),
      "网络收藏": ft.Text("这是网络收藏页面", bgcolor=ft.colors.ORANGE),
      "电脑清理": ft.Text("这是电脑清理页面", bgcolor=ft.colors.GREEN),
      "系统修复": ft.Text("这是系统修复页面", bgcolor=ft.colors.BLUE),
      "我的笔记": ft.Text("这是我的笔记页面", bgcolor=ft.colors.PURPLE),
      "功能大全": ft.Text("这是功能大全页面", bgcolor=ft.colors.YELLOW),
    }

    def tab_clicked(e):
      nonlocal current_tab
      tab_text = e.control.content.controls.controls.value# 获取被点击的标签文本
      print(f"{tab_text} tab clicked")

      # 更新当前标签的背景颜色
      if current_tab:
            current_tab.bgcolor = ft.colors.LIGHT_GREEN# 将之前的标签背景色改为亮绿色
            page.update(current_tab)

      current_tab = e.control
      current_tab.bgcolor = ft.colors.YELLOW# 将当前点击的标签背景色改为黄色
      page.update(current_tab)

      # 更新内容容器中的内容
      content_container.clean()# 清空旧内容
      content_container.controls.append(tab_contents.get(tab_text, ft.Text("未知页面")))
      page.update(content_container)

    # 创建并添加所有标签
    tabs = ft.Row(
      [
            CustomTab(text="我的通讯", icon_path="aa.png", on_click=tab_clicked).build(),
            CustomTab(text="网络收藏", icon_path="bb.png", on_click=tab_clicked).build(),
            CustomTab(text="电脑清理", icon_path="cc.png", on_click=tab_clicked).build(),
            CustomTab(text="系统修复", icon_path="dd.png", on_click=tab_clicked).build(),
            CustomTab(text="我的笔记", icon_path="ee.png", on_click=tab_clicked).build(),
            CustomTab(text="功能大全", icon_path="ff.png", on_click=tab_clicked).build(),
      ],
      alignment=ft.MainAxisAlignment.START
    )

    page.add(tabs, content_container)# 添加标签和内容容器到页面

ft.app(target=main)
3. 表明说明
让我们具体说明一下代码中的颜色变化逻辑及其具体实现方式。
颜色变化逻辑概述
在这个代码中,实现了标签点击时背景颜色的变化逻辑。具体来说,有以下几个关键点:
初始状态:
所有标签的初始背景致均为亮绿色 (ft.colors.LIGHT_GREEN)。
点击事件处理:
当用户点击某个标签时,会触发 tab_clicked 函数。
在 tab_clicked 函数中,起首获取当前被点击的标签文本。
如果之前有选中的标签(即 current_tab 不为 None),则将它的背景致规复为亮绿色。
将当前点击的标签背景致改为黄色 (ft.colors.YELLOW)。
更新页面以反映背景颜色的变化。
页面更新:
只对必要的控件举行更新,以淘汰页面重绘的次数。
具体来说,先更新之前的标签背景致,再更新当前点击的标签背景致,末了更新内容容器中的内容。
具体步调说明
初始化标签:
每个标签的初始背景致设置为亮绿色 (ft.colors.LIGHT_GREEN)。
标签的 on_click 属性绑定到 tab_clicked 函数。
点击事件处理:
tab_clicked 函数吸收点击事件 e。
获取当前点击的标签文本。
如果之前有选中的标签(即 current_tab 不为 None),将其背景致规复为亮绿色,并更新页面。
将当前点击的标签背景致改为黄色,并更新页面。
清空内容容器,并添加新的页面内容。
打造升级版自定义选项卡组件任务完成,自定义选项卡组件更加优秀。
Flet组件tabs自主创新自定义组件升级版CustomTab Pro源代码
修改标签被选中时会改变样式以指示其活动状态,打造升级版自定义选项卡组件。
未选中图标背景为light green,选中背景变为yellow,通过标签被选中时会改变样式以指示其活动状态。初始为:未选中。
CustomTab类:这是一个自定义类,用于创建每个标签都有独特的自定义样式,自定义图标和文本的标签。每个标签可以指定文本、图标路径以及可选的点击事件处理函数。
main函数:这是应用程序的主入口点,定义了页面结构和交互逻辑。
初始化变量current_tab用于跟踪当前选中的标签。
content_container是一个Column控件,用于动态展示差别标签对应的内容。
定义了一个字典tab_contents,此中键是标签的文本,值是与这些标签关联的内容组件。
tab_clicked函数处理标签被点击时的行为,包括更新当前标签的状态(背景颜色)和更新内容容器以显示新的内容。
创建了一个包罗多个CustomTab实例的水平结构Row,这些实例分别代表差别的标签,并且为每个标签指定了点击事件处理器。
末了将标签栏和内容容器添加到页面上,并通过ft.app(target=main)启动应用程序。
团体来看,这段代码实现了一个新奇漂亮的标签切换界面,用户可以通过点击雅观漂亮的标签来欣赏差别的内容区域。每个标签都有独特的自定义样式,自定义图标和文本,并且在被选中时会改变样式以指示其活动状态。
4.运行结果,截图为证
https://i-blog.csdnimg.cn/direct/2689a646b4524689b195601a3f7b3d5a.png#pic_center
四、customtab Pro自定义选项卡升级版组件标签选中和未选中两种背景颜色变化重新配色,并且给选项卡标签启用墨水结果打造自定义选项卡升级版再升级版customtab Pro_up

1.编程思路
bgcolor=ft.colors.GREEN_200, # 背景颜色设置为浅绿色,bgcolor=ft.colors.AMBER, # 背景颜色设置为琥珀色。
设置ink=True, # 启用墨水结果。给自定义选项卡标签开启墨水结果。这将使恰当用户点击或触摸选项卡标签时,会出现一个视觉反馈,即所谓的“墨水溅洒”结果。
2.示例代码

import flet as ft

class CustomTab:
    def __init__(self, text, icon_path, on_click=None):
      self.text = text
      self.icon_path = icon_path
      self.on_click = on_click
      self.bgcolor = ft.colors.GREEN_200# 设置初始背景色为浅绿色

    def build(self):
      # 创建显示图标的行
      image_row = ft.Row(
            ,
            alignment=ft.MainAxisAlignment.CENTER
      )
      # 创建显示文本的行
      text_row = ft.Row(
            ,
            alignment=ft.MainAxisAlignment.CENTER
      )
      # 创建包含图标和文本的列
      container = ft.Column(
            ,
            alignment=ft.MainAxisAlignment.CENTER,
            horizontal_alignment=ft.CrossAxisAlignment.CENTER,
            spacing=5
      )
      # 添加 ink 效果
      return ft.Container(
            content=container,
            bgcolor=self.bgcolor,# 使用类变量来设置背景色
            height=128,
            width=128,
            border_radius=8,
            on_click=self.on_click,
            ink=True# 添加墨水效果
      )

def main(page: ft.Page):
    current_tab = None
    content_container = ft.Column()# 用于显示页面内容的容器

    # 定义每个标签对应的内容
    tab_contents = {
      "我的通讯": ft.Text("这是我的通讯页面", bgcolor=ft.colors.RED),
      "网络收藏": ft.Text("这是网络收藏页面", bgcolor=ft.colors.ORANGE),
      "电脑清理": ft.Text("这是电脑清理页面", bgcolor=ft.colors.GREEN),
      "系统修复": ft.Text("这是系统修复页面", bgcolor=ft.colors.BLUE),
      "我的笔记": ft.Text("这是我的笔记页面", bgcolor=ft.colors.PURPLE),
      "功能大全": ft.Text("这是功能大全页面", bgcolor=ft.colors.YELLOW),
    }

    def tab_clicked(e):
      nonlocal current_tab
      tab_text = e.control.content.controls.controls.value# 获取被点击的标签文本
      print(f"{tab_text} tab clicked")

      # 更新当前标签的背景颜色
      if current_tab:
            current_tab.bgcolor = ft.colors.GREEN_200# 将之前的标签背景色改为浅绿色
            page.update(current_tab)

      current_tab = e.control
      current_tab.bgcolor = ft.colors.AMBER# 将当前点击的标签背景色改为琥珀色
      page.update(current_tab)

      # 更新内容容器中的内容
      content_container.clean()# 清空旧内容
      content_container.controls.append(tab_contents.get(tab_text, ft.Text("未知页面")))
      page.update(content_container)

    # 创建并添加所有标签
    tabs = ft.Row(
      [
            CustomTab(text="我的通讯", icon_path="aa.png", on_click=tab_clicked).build(),
            CustomTab(text="网络收藏", icon_path="bb.png", on_click=tab_clicked).build(),
            CustomTab(text="电脑清理", icon_path="cc.png", on_click=tab_clicked).build(),
            CustomTab(text="系统修复", icon_path="dd.png", on_click=tab_clicked).build(),
            CustomTab(text="我的笔记", icon_path="ee.png", on_click=tab_clicked).build(),
            CustomTab(text="功能大全", icon_path="ff.png", on_click=tab_clicked).build(),
      ],
      alignment=ft.MainAxisAlignment.START
    )

    page.add(tabs, content_container)# 添加标签和内容容器到页面

ft.app(target=main)

3. 表明说明
为了给选项卡的标签添加墨水结果(Ink Effect),我们需要修改 CustomTab 类中的 build 方法,具体是在 ft.Container 控件中添加 ink=True 参数。这将使恰当用户点击或触摸选项卡时,会出现一个视觉反馈,即所谓的“墨水溅洒”结果。通过在 ft.Container 中添加 ink=True 参数,我们实现了选项卡的墨水结果。当用户点击某个选项卡时,将会看到一个短暂的视觉反馈。
**4. 运行结果,截图为证 **
https://i-blog.csdnimg.cn/direct/31f7e2ac25ad48089681493e4620ab58.png#pic_center
五、对应编程任务修改相关文字和图标

1.编程思路
修改相关文字和图标适应购物清单助手桌面程序需求。
2.示例代码
import flet as ft

class CustomTab:
    def __init__(self, text, icon_path, on_click=None):
      self.text = text
      self.icon_path = icon_path
      self.on_click = on_click
      self.bgcolor = ft.colors.GREEN_200# 设置初始背景色为浅绿色

    def build(self):
      # 创建显示图标的行
      image_row = ft.Row(
            ,
            alignment=ft.MainAxisAlignment.CENTER
      )
      # 创建显示文本的行
      text_row = ft.Row(
            ,
            alignment=ft.MainAxisAlignment.CENTER
      )
      # 创建包含图标和文本的列
      container = ft.Column(
            ,
            alignment=ft.MainAxisAlignment.CENTER,
            horizontal_alignment=ft.CrossAxisAlignment.CENTER,
            spacing=5
      )
      # 添加 ink 效果
      return ft.Container(
            content=container,
            bgcolor=self.bgcolor,# 使用类变量来设置背景色
            height=128,
            width=128,
            border_radius=8,
            on_click=self.on_click,
            ink=True# 添加墨水效果
      )

def main(page: ft.Page):
    current_tab = None
    content_container = ft.Column()# 用于显示页面内容的容器

    # 定义每个标签对应的内容
    tab_contents = {
      "我的选购": ft.Text("这是我的选购页面", bgcolor=ft.colors.RED),
      "清单详情": ft.Text("这是清单详情页面", bgcolor=ft.colors.ORANGE),
      "添加商品": ft.Text("这是添加商品页面", bgcolor=ft.colors.GREEN),
      "保存商品": ft.Text("这是保存商品页面", bgcolor=ft.colors.BLUE),
      "删除商品": ft.Text("这是删除商品页面", bgcolor=ft.colors.PURPLE),
      "联系我们": ft.Text("这是联系我们页面", bgcolor=ft.colors.YELLOW),
    }

    def tab_clicked(e):
      nonlocal current_tab
      tab_text = e.control.content.controls.controls.value# 获取被点击的标签文本
      print(f"{tab_text} tab clicked")

      # 更新当前标签的背景颜色
      if current_tab:
            current_tab.bgcolor = ft.colors.GREEN_200# 将之前的标签背景色改为浅绿色
            page.update(current_tab)

      current_tab = e.control
      current_tab.bgcolor = ft.colors.AMBER# 将当前点击的标签背景色改为琥珀色
      page.update(current_tab)

      # 更新内容容器中的内容
      content_container.clean()# 清空旧内容
      content_container.controls.append(tab_contents.get(tab_text, ft.Text("未知页面")))
      page.update(content_container)

    # 创建并添加所有标签
    tabs = ft.Row(
      [
            CustomTab(text="我的选购", icon_path="gg.png", on_click=tab_clicked).build(),
            CustomTab(text="清单详情", icon_path="hh.png", on_click=tab_clicked).build(),
            CustomTab(text="添加商品", icon_path="ii.png", on_click=tab_clicked).build(),
            CustomTab(text="保存商品", icon_path="jj.png", on_click=tab_clicked).build(),
            CustomTab(text="删除商品", icon_path="kk.png", on_click=tab_clicked).build(),
            CustomTab(text="联系我们", icon_path="ll.png", on_click=tab_clicked).build(),
      ],
      alignment=ft.MainAxisAlignment.START
    )

    page.add(tabs, content_container)# 添加标签和内容容器到页面

ft.app(target=main)
3. 表明说明
我们按照要求修改标签的文本和图标路径。
我的通讯 修改为 我的选购,图标为 gg.png
网络收藏 修改为 清单详情,图标为 hh.png
电脑清理 修改为 添加商品,图标为 ii.png
系统修复 修改为 保存商品,图标为 jj.png
我的条记 修改为 删除商品,图标为 kk.png
功能大全 修改为 联系我们,图标为 ll.png
**4. 运行结果,截图为证 **
https://i-blog.csdnimg.cn/direct/cf0c03ba702844f29fee812157839692.png#pic_center
六、利用Flet框架和自定义选项卡customtab Pro组件自定义标题栏实现仿360安全卫士界面自定义模板示例

1.编程思路
自定义选项卡customtab Pro组件自定义标题栏实现仿360安全卫士界面自定义模板
2.示例代码


import flet as ft

class CustomTab:
    def __init__(self, text, icon_path, on_click=None):
      self.text = text
      self.icon_path = icon_path
      self.on_click = on_click
      self.container = None

    def build(self):
      self.container = ft.Container(
            content=ft.Column(
                controls=[
                  ft.Row(
                        controls=,
                        alignment=ft.MainAxisAlignment.CENTER
                  ),
                  ft.Row(
                        controls=,
                        alignment=ft.MainAxisAlignment.CENTER
                  )
                ],
                alignment=ft.MainAxisAlignment.CENTER,
                spacing=5
            ),
            bgcolor=ft.colors.GREEN_500,
            height=200,
            width=200,
            on_click=self.on_click,
            ink=True# 确保具有墨水效果
      )
      return self.container

def create_tab(text, icon_path, on_click):
    return CustomTab(text=text, icon_path=icon_path, on_click=on_click).build()

def main(page: ft.Page):
    # 设置窗口的初始大小和样式
    page.window.width = 1220
    page.window.height = 800
    page.window.frameless = True
    page.window.resizable = False

    current_tab = None
    content_container = ft.Column()

    tab_contents = {
      "我的选购": ft.Text("这是我的选购页面", bgcolor=ft.colors.RED),
      "清单详情": ft.Text("这是清单详情页面", bgcolor=ft.colors.ORANGE),
      "添加商品": ft.Text("这是添加商品页面", bgcolor=ft.colors.GREEN),
      "保存商品": ft.Text("这是保存商品页面", bgcolor=ft.colors.BLUE),
      "删除商品": ft.Text("这是删除商品页面", bgcolor=ft.colors.PURPLE),
      "联系我们": ft.Text("这是联系我们页面", bgcolor=ft.colors.YELLOW),
    }

    def tab_clicked(e):
      nonlocal current_tab
      tab_text = e.control.content.controls.controls.value
      print(f"{tab_text} tab clicked")

      if current_tab:
            current_tab.bgcolor = ft.colors.GREEN_500
      
      current_tab = e.control
      current_tab.bgcolor = ft.colors.GREEN_200
      page.update()

      content_container.clean()
      content_container.controls.append(tab_contents)
      page.update()

    # 创建顶部标题栏
    def create_app_title():
      app_title_row = ft.Row(
            controls=[
                ft.IconButton(ft.icons.SHOPPING_CART, tooltip="购物车", icon_color=ft.colors.WHITE),
                ft.Text("购物清单助手桌面程序1.0", color=ft.colors.WHITE, size=16)
            ],
            alignment=ft.MainAxisAlignment.START
      )
      close_button = ft.IconButton(
            ft.icons.CLOSE,
            tooltip="关闭",
            icon_color=ft.colors.RED,
            on_click=lambda e: page.window.close()
      )
      icons_row = ft.Row(
            controls=[
                ft.IconButton(ft.icons.HOME, tooltip="首页", icon_color=ft.colors.WHITE),
                ft.IconButton(ft.icons.SEARCH, tooltip="搜索", icon_color=ft.colors.WHITE),
                ft.IconButton(ft.icons.SETTINGS, tooltip="设置", icon_color=ft.colors.WHITE),
                close_button
            ],
            alignment=ft.MainAxisAlignment.END
      )
      top_row_container = ft.Container(
            content=ft.Row(
                controls=,
                alignment=ft.MainAxisAlignment.SPACE_BETWEEN,
                height=50,
                width=1220
            ),
            bgcolor=ft.colors.GREEN_500,
            padding=10,
      )
      return top_row_container

    # 创建标签栏
    def create_tabs():
      tabs = ft.Row(
            [
                create_tab(text="我的选购", icon_path="gg.png", on_click=tab_clicked),
                create_tab(text="清单详情", icon_path="hh.png", on_click=tab_clicked),
                create_tab(text="添加商品", icon_path="ii.png", on_click=tab_clicked),
                create_tab(text="保存商品", icon_path="jj.png", on_click=tab_clicked),
                create_tab(text="删除商品", icon_path="kk.png", on_click=tab_clicked),
                create_tab(text="联系我们", icon_path="ll.png", on_click=tab_clicked),
            ],
            alignment=ft.MainAxisAlignment.START,
            spacing=0,
            width=1200
      )
      return tabs

    # 创建布局
    layout_column = ft.Column(
      controls=,
      spacing=0
    )

    page.add(layout_column, content_container)

ft.app(target=main)

3. 表明说明
这段代码的特色包括:
自定义组件:通过定义 CustomTab 类,创建了可重复利用的选项卡组件,方便管理与展示差别的功能,使得代码结构更加清晰和模块化。
用户界面设计:应用程序的界面设计考虑告终构的雅观性和实用性,利用了图标和文本,增强了用户体验。顶部区域有明显的标题和功能图标,易于识别。
互动性:选项卡的点击事件处理增强了应用的互动性,用户点击差别的选项卡后,可以动态更换页面内容,使得操作更加流畅和直观。还添加了点击选项卡产生墨水结果功能,自定义选项卡视觉结果更加酷炫了。
颜色风格:利用丰富的颜色来区分差别的选项和内容,如 GREEN_500 和 GREEN_200,不仅雅观,还能有效引导用户注意力。
机动性与可扩展性:通过利用字典 tab_contents 来存储各选项卡的内容,使得后期扩展更为简单,能够轻松添加新的功能或页面。
窗体属性设置:通过设置窗口的大小、边框以及可调整性,增强了应用的适应性,提供了更加专注的用户体验(如无边框设计)。
响应式结构:团体结构利用了 Flet 提供的响应式控件(如 Row 和 Column),使得元素能够在差别分辨率的窗口中合理排列。
这些特色结合在一起,形成了一个结构清晰、易于利用且具备漂亮雅观用户界面的桌面应用程序UI界面。
**4. 运行结果,截图为证 **
https://i-blog.csdnimg.cn/direct/b3e13706dba14eba8069fc30b1cdfea3.png
七、购物清单助手桌面程序框架搭建完毕,二次开发有了基础

1.编程思路
在我的选购内容页面添加输入框和添加、保存、删除三个按钮,添加列表视图。在清单详情内容页面添加数据表。合理结构,美化界面。实现购物清单助手的功能逻辑。在我的联系内容页面实现作者logo圆形头像加载。实现作者创作信息文字加载。利用sqlite3数据库实现数据永久加载。还有几个内容页面有待进一步扩展功能,二次开发。
完成搭建购物清单助手桌面程序框架的工作,二次开发有了脚手架和基本框架。开源发布,允许修改源代码二次开发,允许商业开发。
2.示例代码

import flet as ft
import sqlite3
import os

# 常量定义
DB_NAME = 'shopping_list.db'
PRIMARY_COLOR = ft.colors.GREEN_500
SECONDARY_COLOR = ft.colors.GREEN_400
BG_COLOR = ft.colors.WHITE
WINDOW_WIDTH = 1248
WINDOW_HEIGHT = 840

class ShoppingListApp:
    def __init__(self):
      self.page = None
      self.items = []
      self.current_tab = None
      self.name_field = None
      self.list_view = None
      self.data_table = None
      self.tab_contents = None

    def init_db(self):
      if not os.path.exists(DB_NAME):
            with sqlite3.connect(DB_NAME) as conn:
                c = conn.cursor()
                c.execute('''CREATE TABLE items (name TEXT, checked INTEGER)''')

    def add_item_to_db(self, name, checked=0):
      with sqlite3.connect(DB_NAME) as conn:
            c = conn.cursor()
            c.execute("INSERT INTO items VALUES (?, ?)", (name, checked))

    def get_items_from_db(self):
      with sqlite3.connect(DB_NAME) as conn:
            c = conn.cursor()
            c.execute("SELECT * FROM items")
            return [{"name": row, "checked": bool(row)} for row in c.fetchall()]

    def update_item_in_db(self, name, checked):
      with sqlite3.connect(DB_NAME) as conn:
            c = conn.cursor()
            c.execute("UPDATE items SET checked = ? WHERE name = ?", (int(checked), name))

    def delete_item_from_db(self, name):
      with sqlite3.connect(DB_NAME) as conn:
            c = conn.cursor()
            c.execute("DELETE FROM items WHERE name = ?", (name,))

    def add_item_to_list(self, e):
      item_name = self.name_field.value
      if item_name:
            self.add_item_to_db(item_name)
            self.items = self.get_items_from_db()
            self.update_list_view()
            self.name_field.value = ""
            self.page.update()

    def update_list_view(self):
      self.items = self.get_items_from_db()
      self.list_view.controls.clear()
      for item in self.items:
            checkbox = ft.Checkbox(value=item["checked"])
            checkbox.on_change = lambda e, item=item: self.toggle_item_status(e, item)
            
            # 创建一个居中的文本控件
            centered_text = ft.Container(
                content=ft.Text(item["name"], size=16),
                alignment=ft.alignment.center,
                expand=True
            )
            
            # 将复选框和文本放在一个水平行中
            row = ft.Row(
                controls=[
                  checkbox,
                  centered_text
                ],
                alignment=ft.MainAxisAlignment.CENTER,
                vertical_alignment=ft.CrossAxisAlignment.CENTER,
                width=780# 设置一个固定宽度,稍小于容器宽度
            )
            
            # 将行包装在一个容器中
            item_container = ft.Container(
                content=row,
                alignment=ft.alignment.center,
                width=800,
                border=ft.border.all(1, ft.colors.GREY_400),
                border_radius=5,
                padding=5
            )
            
            self.list_view.controls.append(item_container)
      self.page.update()

    def update_data_table(self, e=None):
      self.items = self.get_items_from_db()
      self.data_table.rows.clear()
      for item in self.items:
            status = "已购买" if item["checked"] else "未购买"
            self.data_table.rows.append(
                ft.DataRow(cells=)), ft.DataCell(ft.Text(status))])
            )
      self.page.update()

    def toggle_item_status(self, e, item):
      item["checked"] = e.control.value
      self.update_item_in_db(item["name"], item["checked"])
      self.page.update()

    def delete_selected_items(self, e):
      for item in self.items:
            if item["checked"]:
                self.delete_item_from_db(item["name"])
      self.items = self.get_items_from_db()
      self.update_list_view()

    def tab_clicked(self, e):
      tab_text = e.control.content.controls.controls.value
      print(f"{tab_text} 标签被点击")

      if self.current_tab:
            self.current_tab.bgcolor = PRIMARY_COLOR
      
      self.current_tab = e.control
      self.current_tab.bgcolor = SECONDARY_COLOR
      self.page.update()

      content_container = self.page.controls.content.controls
      content_container.clean()
      content_container.controls.append(self.tab_contents)
      
      if tab_text == "我的选购":
            self.update_list_view()
      elif tab_text == "清单详情":
            self.update_data_table()
      
      self.page.update()

    def create_app_title(self):
      app_title_row = ft.Row(
            controls=[
                ft.IconButton(ft.icons.SHOPPING_CART, tooltip="购物车", icon_color=BG_COLOR),
                ft.Text("购物清单助手桌面程序1.0", color=BG_COLOR, size=16)
            ],
            alignment=ft.MainAxisAlignment.START
      )
      close_button = ft.IconButton(
            ft.icons.CLOSE,
            tooltip="关闭",
            icon_color=ft.colors.RED,
            on_click=lambda _: self.page.window.close()
      )
      icons_row = ft.Row(
            controls=[
                ft.IconButton(ft.icons.ADD, tooltip="添加", icon_color=ft.colors.GREEN, on_click=self.add_item_to_list),
                ft.IconButton(ft.icons.HELP, tooltip="帮助", icon_color=ft.colors.BLUE, on_click=lambda _: print("帮助按钮点击")),
                ft.IconButton(ft.icons.INFO, tooltip="关于", icon_color=ft.colors.RED, on_click=lambda _: print("关于按钮点击")),
                close_button
            ],
            alignment=ft.MainAxisAlignment.END
      )
      return ft.Container(
            content=ft.Row(
                controls=,
                alignment=ft.MainAxisAlignment.SPACE_BETWEEN,
                height=50,
                width=1200
            ),
            bgcolor=PRIMARY_COLOR,
            padding=10,
      )

    def create_tabs(self):
      return ft.Row(
            [
                self.create_tab(text="我的选购", icon_path="gg.png", on_click=self.tab_clicked),
                self.create_tab(text="清单详情", icon_path="hh.png", on_click=self.tab_clicked),
                self.create_tab(text="添加商品", icon_path="ii.png", on_click=self.tab_clicked),
                self.create_tab(text="保存商品", icon_path="jj.png", on_click=self.tab_clicked),
                self.create_tab(text="删除商品", icon_path="kk.png", on_click=self.tab_clicked),
                self.create_tab(text="联系我们", icon_path="ll.png", on_click=self.tab_clicked),
            ],
            alignment=ft.MainAxisAlignment.START,
            spacing=0,
            width=1260
      )

    def create_tab(self, text, icon_path, on_click):
      return ft.Container(
            content=ft.Column(
                controls=[
                  ft.Row(controls=, alignment=ft.MainAxisAlignment.CENTER),
                  ft.Row(controls=, alignment=ft.MainAxisAlignment.CENTER)
                ],
                alignment=ft.MainAxisAlignment.CENTER,
                spacing=5
            ),
            bgcolor=PRIMARY_COLOR,
            height=200,
            width=200,
            on_click=on_click,
            ink=True
      )

    def create_layout(self):
      self.name_field = ft.TextField(label="请输入商品名称", width=500)
      self.list_view = ft.ListView(expand=1, spacing=10, padding=10, auto_scroll=True)
      self.data_table = ft.DataTable(
            columns=,
            rows=[],
      )

      my_selections_content = ft.Container(
            content=ft.Column(
                controls=[
                  ft.Container(
                        height=100,
                        content=ft.Row(
                            controls=[
                              self.name_field,
                              ft.IconButton(ft.icons.ADD, tooltip="添加", icon_color=ft.colors.GREEN, on_click=self.add_item_to_list),
                              ft.IconButton(ft.icons.SAVE, tooltip="保存", icon_color=ft.colors.BLUE, on_click=self.update_data_table),
                              ft.IconButton(ft.icons.DELETE, tooltip="删除", icon_color=ft.colors.RED, on_click=self.delete_selected_items)
                            ],
                            alignment=ft.MainAxisAlignment.CENTER
                        )
                  ),
                  ft.Container(
                        content=self.list_view,
                        width=800,
                        height=400,
                        border=ft.border.all(1, ft.colors.GREY_400),
                        border_radius=5,
                        padding=10
                  )
                ],
                spacing=10,
                alignment=ft.MainAxisAlignment.START,
                horizontal_alignment=ft.CrossAxisAlignment.CENTER,
            ),
            width=1200,
            height=522,
            bgcolor=ft.colors.WHITE,
            padding=10,
      )

      contact_us_content = ft.Container(
            content=ft.Column(
                controls=[
                  ft.Container(
                        content=ft.Image(src="logo.jpg", width=200, height=200, fit=ft.ImageFit.COVER),
                        width=200, height=200, border_radius=100, clip_behavior=ft.ClipBehavior.ANTI_ALIAS, margin=50
                  ),
                  ft.Text("购物清单助手桌面程序1.0", size=20, weight=ft.FontWeight.BOLD),
                  ft.Text("传奇开心果基于FLet创意编程", size=16),
                  ft.Text("2024年10月14日于瓜州家中完成作品", size=16),
                ],
                alignment=ft.MainAxisAlignment.CENTER,
                horizontal_alignment=ft.CrossAxisAlignment.CENTER,
                spacing=20,
            ),
            alignment=ft.alignment.center,
            width=1200,
            height=522,
            bgcolor=ft.colors.WHITE,
            padding=10,
      )

      self.tab_contents = {
            "我的选购": my_selections_content,
            "清单详情": ft.Container(
                content=ft.Column(
                  controls=[
                        ft.Container(content=ft.Text("商品清单", size=20, weight=ft.FontWeight.BOLD), alignment=ft.alignment.center),
                        ft.Container(
                            content=ft.ListView(
                              [
                                    ft.Container(
                                        content=self.data_table,
                                        width=800,
                                    )
                              ],
                              expand=1,
                              spacing=10,
                              padding=20,
                              auto_scroll=True
                            ),
                            width=800,
                            height=400,
                            border=ft.border.all(1, ft.colors.GREY_400),
                            border_radius=5,
                        )
                  ],
                  spacing=20,
                  alignment=ft.MainAxisAlignment.CENTER,
                  horizontal_alignment=ft.CrossAxisAlignment.CENTER
                ),
                width=1200,
                height=522,
                bgcolor=ft.colors.WHITE,
                padding=10,
            ),
            "添加商品": ft.Container(
                content=ft.Text("这是添加商品页面"),
                width=1200,
                height=522,
                bgcolor=ft.colors.WHITE,
                padding=10,
                alignment=ft.alignment.center
            ),
            "保存商品": ft.Container(
                content=ft.Text("这是保存商品页面"),
                width=1200,
                height=522,
                bgcolor=ft.colors.WHITE,
                padding=10,
                alignment=ft.alignment.center
            ),
            "删除商品": ft.Container(
                content=ft.Text("这是删除商品页面"),
                width=1200,
                height=522,
                bgcolor=ft.colors.WHITE,
                padding=10,
                alignment=ft.alignment.center
            ),
            "联系我们": contact_us_content,
      }

      return ft.Column(controls=, spacing=0)

    def main(self, page: ft.Page):
      self.page = page
      self.init_db()
      self.items = self.get_items_from_db()
      
      self.page.window.width = WINDOW_WIDTH
      self.page.window.height = WINDOW_HEIGHT
      self.page.window.frameless = True
      self.page.window.resizable = False
      
      self.page.bgcolor = BG_COLOR
      self.page.padding = 20

      main_container = ft.Container(
            content=ft.Column(spacing=0),
            expand=True,
            bgcolor=ft.colors.GREY_200,
            border=ft.border.all(2, PRIMARY_COLOR),
            padding=2
      )

      content_container = ft.Column()

      layout_column = self.create_layout()
      main_container.content.controls.extend()
      self.page.add(main_container)

      # 默认选中"我的选购"标签并加载数据
      self.current_tab = layout_column.controls.controls
      self.current_tab.bgcolor = SECONDARY_COLOR
      content_container.controls.append(self.tab_contents["我的选购"])
      self.update_list_view()

if __name__ == "__main__":
    app = ShoppingListApp()
    ft.app(target=app.main)

3. 表明说明
这个购物清单助手桌面程序有以下几个特色:
A. 界面设计雅观:
利用了绿色主题,搭配白色背景,视觉结果清新。
接纳了无边框设计(frameless),给人当代感。
顶部有应用标题和功能图标,结构合理。
B. 标签式导航:
利用了六个主要功能标签,每个标签都有图标和文字说明。
标签点击后会改变颜色,提供视觉反馈。
C. 数据长期化:
利用 SQLite 数据库存储购物清单项目,确保数据可以长期保存。
D. 功能丰富:
可以添加、删除、标记已购买的商品。
提供列表视图和表格视图两种方式展示购物清单。
支持批量删除已购买的商品。
E. 响应式设计:
窗口大小固定,但内部结构能够适应差别内容。
利用 ListView 实现长列表的滚动结果。
F. 自定义组件:
创建了自定义的标签组件,包罗图标和文字。
商品列表项利用了自定义的容器设计,包括复选框和居中文本。
G. 模块化结构:
代码构造清晰,利用类的方式封装了应用的各个功能。
将差别页面的内容分别定义,便于管理和扩展。
H交互设计:
提供了添加、保存、删除等快捷操作按钮。
标签切换时有明显的视觉反馈。
I. 关于页面:
包罗了一个圆形的 logo 图像和应用信息,体现了个性化设计。
J. 错误处理:
固然代码中没有明白的错误处理机制,但基本的输入验证(如空输入检查)已经实现。
K. 可扩展性:
预留了"添加商品"、“保存商品”、"删除商品"等标签页面,为未来功能扩展做好了准备。
总结
总的来说,这个应用展示了如何利用 Flet 框架创建一个功能完备、界面雅观的桌面应用程序。它结合了数据库操作、UI 设计和用户交互等多个方面,是一个很好的实践示例。
**4. 运行结果,截图为证 **
https://i-blog.csdnimg.cn/direct/e232cf427437415ca9a5e6459ca70b00.png#pic_center
https://i-blog.csdnimg.cn/direct/892e09cd56494606ace20395d7ea24cb.png#pic_center
https://i-blog.csdnimg.cn/direct/072c18e51e5040fc87172cfb194ea69c.png#pic_center
八、全文总结

这是我利用了Flet框架一段时间以后的反思顿悟,又是豪情澎湃的文学表达,也是自主创新自定义控件创意编程灵感的舞蹈,也是循规蹈矩谆谆教导通俗易懂雅俗共赏的Flet框架桌面程序开发教学教程,更是Flet框架触动灵魂的切身段验!也是我东临碣石,以观沧海心潮难平的胸臆抒怀!
我个人以为,flet打包安卓手机应用应该和谷歌和苹果公司互助定制一个专用移动应用打包工具,而且是图形化界面的如许才专业。才有利于flet框架在全球的快速遍及。才不至于成为小众UI框架。星星之火,可以燎原,flet框架就是如许,有那么一天会风靡全球,这是我的预言。
背靠谷歌和苹果,大树底下好乘凉,生态很快就能成长起来。没有大动作,生态上成长不起来,就走不出小众UI框架的困局。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 【易上手快捷开发新框架技术】Flet购物清单助手桌面版分步调示例、自主创新