使用Flet开发的购物清单助手桌面程序v1.0脚手架和基本框架源代码开源发布,IDE运行和调试通过

传奇开心果编程
优质创作者: python技术领域
2024-10-15 10:14:42

img

img

img

一、编程思路

完成搭建购物清单助手桌面程序框架的工作,二次开发有了脚手架和基本框架。开源发布,允许修改源代码二次开发,允许商业开发。

二、示例代码


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[0], "checked": bool(row[1])} 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(item["name"])), 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[1].controls[0].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[0].content.controls[1]
        content_container.clean()
        content_container.controls.append(self.tab_contents[tab_text])
        
        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=[app_title_row, icons_row],
                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=[ft.Image(src=icon_path, width=64, height=64)], alignment=ft.MainAxisAlignment.CENTER),
                    ft.Row(controls=[ft.Text(text, color=BG_COLOR, size=16)], 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=[ft.DataColumn(ft.Text("商品名称")), ft.DataColumn(ft.Text("状态"))],
            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=[self.create_app_title(), self.create_tabs()], 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([layout_column, content_container])
        self.page.add(main_container)

        # 默认选中"我的选购"标签并加载数据
        self.current_tab = layout_column.controls[1].controls[0]
        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)

三、解释说明

这个购物清单助手桌面程序有以下几个特色:
1. 界面设计美观:
使用了绿色主题,搭配白色背景,视觉效果清新。
采用了无边框设计(frameless),给人现代感。
顶部有应用标题和功能图标,布局合理。
2. 标签式导航:
使用了六个主要功能标签,每个标签都有图标和文字说明。
标签点击后会改变颜色,提供视觉反馈。
3. 数据持久化:
使用 SQLite 数据库存储购物清单项目,确保数据可以长期保存。
4. 功能丰富:
可以添加、删除、标记已购买的商品。
提供列表视图和表格视图两种方式展示购物清单。
支持批量删除已购买的商品。
5. 响应式设计:
窗口大小固定,但内部布局能够适应不同内容。
使用 ListView 实现长列表的滚动效果。
6. 自定义组件:
创建了自定义的标签组件,包含图标和文字。
商品列表项使用了自定义的容器设计,包括复选框和居中文本。
7. 模块化结构:
代码组织清晰,使用类的方式封装了应用的各个功能。
将不同页面的内容分别定义,便于管理和扩展。
8. 交互设计:
提供了添加、保存、删除等快捷操作按钮。
标签切换时有明显的视觉反馈。
9. 关于页面:
包含了一个圆形的 logo 图像和应用信息,体现了个性化设计。
10. 错误处理:
虽然代码中没有明确的错误处理机制,但基本的输入验证(如空输入检查)已经实现。
11. 可扩展性:
预留了"添加商品"、"保存商品"、"删除商品"等标签页面,为未来功能扩展做好了准备。

总结

总的来说,这个应用展示了如何使用 Flet 框架创建一个功能完整、界面美观的桌面应用程序。它结合了数据库操作、UI 设计和用户交互等多个方面,是一个很好的实践示例。

四、运行效果,截图为证

效果图见文章最前面。漂亮美观。

...全文
408 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复
这个购物清单助手桌面程序有以下几个特色:界面设计美观:使用了绿色主题,搭配白色背景,视觉效果清新。采用了无边框设计(frameless),给人现代感。顶部有应用标题和功能图标,布局合理。标签式导航:使用了六个主要功能标签,每个标签都有图标和文字说明。标签点击后会改变颜色,提供视觉反馈。数据持久化:使用 SQLite 数据库存储购物清单项目,确保数据可以长期保存。功能丰富:可以添加、删除、标记已购买的商品。提供列表视图和表格视图两种方式展示购物清单。支持批量删除已购买的商品。响应式设计:窗口大小固定,但内部布局能够适应不同内容。使用 ListView 实现长列表的滚动效果。自定义组件:创建了自定义的标签组件,包含图标和文字。商品列表项使用了自定义的容器设计,包括复选框和居中文本。模块化结构:代码组织清晰,使用类的方式封装了应用的各个功能。将不同页面的内容分别定义,便于管理和扩展。 交互设计:提供了添加、保存、删除等快捷操作按钮。标签切换时有明显的视觉反馈。关于页面:包含了一个圆形的 logo 图像和应用信息,体现了个性化设计。错误处理:虽然代码中没有明确的错误处理机制,但基本的输入验证
这是一个使用Python和Flet框架开发的小学数学自动出题判题桌面应用程序。该程序可以帮助小学生练习基本的数学运算,包括加法、减法、乘法和除法。 ## 功能特点 - 自动生成小学数学题目(加减乘除) - 实时判题并显示结果 - 统计功能:显示答题进度和准确率 - 现代化UI设计,支持主题切换(浅色/深色模式) - 数据持久化:自动保存和加载统计数据 - 版权信息显示 - 错误处理和边界检查,增强程序健壮性 ## 安装依赖 确保您的系统已安装Python 3.7或更高版本。 ```bash pip install -r requirements.txt ``` ### 依赖说明 - `flet==0.28.3`: 用于构建桌面应用程序的现代GUI框架 ## 运行程序 ```bash python shuxuezidongchutipanti.py ``` ## 使用说明 1. 程序启动后会自动生成10道数学题目 2. 在输入框中输入答案,点击"提交"按钮或按回车键提交 3. 程序会立即判断答案是否正确并显示结果 4. 可以使用"上一题"和"下一题"按钮切换题目 5. 点击"重新开始"按钮可以生成新的题目 6. 点击右上角的主题按钮可以切换浅色/深色主题 7. 点击"关于"按钮可以查看程序信息 ## 技术实现 - **编程语言**: Python 3.x - **GUI框架**: Flet - **数据存储**: JSON文件 - **主题支持**: 浅色和深色主题切换 ## 代码结构 ``` shuxuezidongchutipanti/ ├── shuxuezidongchutipanti.py # 主程序文件 ├── math_quiz_stats.json # 统计数据文件 ├── requirements.txt

19

社区成员

发帖
与我相关
我的任务
社区描述
近期,感兴趣Ant Design Mobile of React、Vant of Vue 、MUI of h5App、WeUI 原生微信小程序和beeware移动应用开发,发布原创博文创建专栏发布动态
androidios微信小程序 个人社区 甘肃省·酒泉市
社区管理员
  • 传奇开心果编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧