祥云县住房和城乡建设局网站画册设计流程步骤

张小明 2026/1/9 15:32:50
祥云县住房和城乡建设局网站,画册设计流程步骤,深圳有几个区分别是什么,wordpress ftp 备份xml大哥大饭店点餐系统**——Python Tkinter 桌面点餐管理系统#xff08;完整源码分享#xff09;** 项目简介#xff1a;一个基于 Python Tkinter 的轻量级桌面点餐系统#xff0c;适合中小型饭店使用。实现了顾客点餐#xff08;支持辣度、备注#xff09;、管理员登录、…大哥大饭店点餐系统**——Python Tkinter 桌面点餐管理系统完整源码分享**项目简介一个基于 Python Tkinter 的轻量级桌面点餐系统适合中小型饭店使用。实现了顾客点餐支持辣度、备注、管理员登录、菜品管理、订单持久化、营业数据统计与 Matplotlib 可视化展示。全程使用 JSON 文件存储数据无需数据库纯本地运行开箱即用。技术栈Python 3.x、Tkinter、JSON、Matplotlib开发日期2025年12月作者kblj5555前言在学习 Python 编程的过程中学校的课程设计要求我们做一个GUI项目因为家里是开饭店的所以我想做一个贴近自己家庭生活的实战项目先用简单的做一个整体构思框架等并在以后有机会的情况下做一个能用于自己家的小项目。于是我决定开发一个简单实用的大哥大饭店点餐系统。本系统完全使用 Python 标准库 Tkinter 实现界面数据用 JSON 文件持久化统计模块嵌入 Matplotlib 实现图表可视化。整个项目只有 4 个核心 py 文件 3 个 JSON 数据文件结构清晰易于二次开发。本系统开发阶段由于时间紧张所以无法展现完整功能的作品且大量借助了AI的力量所以后续代码的结构不是很完整且若大家代码有什么看不懂的且没有注释希望大家借助AI来帮助自己在这里感谢Tare CN、Gork、豆包对我的帮助。主要功能顾客桌号选择、浏览菜品、双击点餐可选辣度 备注、订单管理、确认下单管理员登录验证、创建管理员账号、菜品管理框架、查看订单、营业额统计按天/按星期 图表数据持久化菜单、用户信息、营业数据全部本地保存重启不丢失下面分享整个开发思路、实现过程和完整源码希望对正在学习 Tkinter 的同学有所帮助整体规划项目结构text大哥大饭店点餐系统/ ├── main.py # 程序入口、主界面、桌号选择、管理者登录 ├── order.py # 顾客点餐核心模块 ├── guanli.py # 管理员管理模块菜品管理、统计入口 ├── shuju.py # 营业数据统计与图表可视化 ├── 用户信息.json # 管理员账号密码默认有几个测试账号 ├── 菜单.json # 菜品信息19道菜示例 ├── 营业数据.json # 历史订单记录 └── README.md # 项目说明就是本文模块职责划分main.py系统启动、欢迎界面、1-9桌选择、管理者登录跳转order.py点餐主逻辑双击点餐、辣度备注、订单增删、确认下单并保存guanli.py管理员界面框架菜品管理基础功能跳转统计shuju.py独立统计窗口按天每小时折线图/按星期每天柱状图支持中文显示数据存储设计全部使用 JSON 文件无需额外安装数据库用户信息.json存储管理员账号、密码、角色菜单.json菜品列表id、name、price、category营业数据.json订单数组订单编号、时间、桌号、菜品详情、总金额具体实现1. 主入口与桌号选择main.py使用九宫格按钮实现1-9桌选择点击后销毁主窗口并传入桌号打开点餐界面。同时提供“管理者登录”入口支持创建新管理员账号。2. 顾客点餐order.py双击菜品弹出辣度清淡/微辣/中辣/爆辣和备注输入框右侧实时显示已选菜品支持删除总金额自动计算确认下单后生成唯一订单编号追加写入 营业数据.json3. 管理员管理guanli.py根据顾客点餐order.py基础框架扩展完整菜品增删改查两者基本上是相同的减少桌号功能。可跳转到统计界面。4. 营业数据统计shuju.py读取所有历史订单支持“按天”查看24小时销售额折线图支持“按星期”查看7天销售额柱状图使用 FigureCanvasTkAgg 将 Matplotlib 图表嵌入 Tkinter 窗口支持中文显示SimHei 字体加分点辣度和备注自定义Matplotlib 完美嵌入 Tkinter相对路径统一项目可直接复制运行管理员账号动态创建完整代码1. main.py程序入口Pythonimporttkinterastfromtkinterimportmessageboxasinfoimportjson,osimportguanli,order currentdiros.path.dirname(os.path.abspath(__file__))USER_INFO_FILEos.path.join(currentdir,用户信息.json)# 读取用户信息defread_user_info():从JSON文件中读取用户信息列表try:withopen(USER_INFO_FILE,r,encodingutf-8)asfile:returnjson.load(file)exceptFileNotFoundError:info.showerror(错误,用户信息文件未找到)return[]# 保存用户信息defsave_user_info(user_info_list):将用户信息列表保存到JSON文件中try:withopen(USER_INFO_FILE,w,encodingutf-8)asfile:json.dump(user_info_list,file,ensure_asciiFalse,indent4)returnTrueexceptExceptionase:info.showerror(错误,f保存用户信息失败:{str(e)})returnFalse# 登录验证defvalidate_login(username,password):验证用户名和密码是否正确 Args: username: 用户名 password: 密码 Returns: 验证成功返回用户信息字典失败返回None user_info_listread_user_info()foruserinuser_info_list:ifuser[账号]usernameanduser[密码]password:returnuserreturnNone# 打开订单系统defopen_order(desk_number):打开订单系统 Args: desk_number: 桌号 try:# 直接调用order模块的create_order_window函数order.create_order_window(str(desk_number))exceptExceptionase:info.showerror(错误,f打开订单系统失败:{str(e)})# 管理者登录窗口defmanager_login_window():打开管理者登录窗口deflogin():处理登录按钮点击事件usernameusername_entry.get()passwordpassword_entry.get()uservalidate_login(username,password)ifuseranduser[角色]管理者:login_window.destroy()open_manager_menu()else:info.showerror(错误,账号或密码错误或无管理者权限)defback_to_main():返回主界面login_window.destroy()main_window()# 返回主界面login_windowt.Tk()login_window.title(管理者登录)login_window.geometry(400x300)# 增大窗口大小login_window.resizable(False,False)t.Label(login_window,text管理者登录,font(宋体,14)).pack(pady10)t.Label(login_window,text账号:).pack(pady5)username_entryt.Entry(login_window)# 账号输入框username_entry.pack()t.Label(login_window,text密码:).pack(pady5)password_entryt.Entry(login_window,show*)# 密码输入框密码以*显示password_entry.pack()button_framet.Frame(login_window)# 创建按钮框架button_frame.pack(pady20)t.Button(button_frame,text登录,commandlogin,width15).pack(sideleft,padx10)t.Button(button_frame,text返回主界面,commandback_to_main,width15).pack(sideleft,padx10)# 管理者菜单defopen_manager_menu():打开管理者菜单窗口defcreate_new_account():创建新管理者账号defsave_new_account():保存新账号new_usernamenew_username_entry.get()new_passwordnew_password_entry.get()new_role管理者ifnotnew_usernameornotnew_password:info.showwarning(警告,账号和密码不能为空)returnuser_info_listread_user_info()# 检查账号是否已存在foruserinuser_info_list:ifuser[账号]new_username:info.showwarning(警告,账号已存在)return# 添加新账号new_user{账号:new_username,密码:new_password,角色:new_role}user_info_list.append(new_user)ifsave_user_info(user_info_list):info.showinfo(成功,新账号创建成功)account_window.destroy()manager_window.destroy()main_window()# 创建成功后返回主界面defback_to_manager_menu():返回管理者菜单account_window.destroy()account_windowt.Toplevel()account_window.title(创建新账号)account_window.geometry(300x250)account_window.resizable(False,False)t.Label(account_window,text创建管理者账号,font(宋体,14)).pack(pady10)t.Label(account_window,text新账号:).pack(pady5)new_username_entryt.Entry(account_window)# 新账号输入框new_username_entry.pack()t.Label(account_window,text新密码:).pack(pady5)new_password_entryt.Entry(account_window,show*)# 新密码输入框new_password_entry.pack()button_framet.Frame(account_window)# 按钮框架button_frame.pack(pady20)t.Button(button_frame,text创建,commandsave_new_account,width12).pack(sideleft,padx5)t.Button(button_frame,text返回,commandback_to_manager_menu,width12).pack(sideleft,padx5)defopen_management_system():打开管理系统try:manager_window.destroy()# 直接调用guanli模块的create_guanli_window函数guanli.create_guanli_window()exceptExceptionase:info.showerror(错误,f打开管理系统失败:{str(e)})defback_to_main():返回主界面manager_window.destroy()main_window()# 返回主界面manager_windowt.Tk()manager_window.title(管理者菜单)manager_window.geometry(400x300)manager_window.resizable(False,False)t.Label(manager_window,text管理者菜单,font(宋体,16)).pack(pady20)t.Button(manager_window,text创建新管理者账号,commandcreate_new_account,width20,height2).pack(pady10)t.Button(manager_window,text打开管理系统,commandopen_management_system,width20,height2).pack(pady10)t.Button(manager_window,text返回主界面,commandback_to_main,width20,height2).pack(pady10)# 主界面defmain_window():打开系统主界面windowt.Tk()window.title(大哥大饭店 - 登录系统)window.geometry(1000x800)window.resizable(False,False)# 欢迎语t.Label(window,text欢迎来到大哥大饭店,font(宋体,24),fgred).pack(pady30)# 桌号按钮区域t.Label(window,text请选择桌号,font(宋体,16)).pack(pady10)# 九宫格按钮布局button_framet.Frame(window)# 创建按钮框架button_frame.pack(pady20)# 创建1-9的桌号按钮foriinrange(1,10):row(i-1)//3# 计算按钮所在行0-2col(i-1)%3# 计算按钮所在列0-2# 创建桌号按钮点击后关闭当前窗口并打开点餐系统同时传递桌号参数btnt.Button(button_frame,textstr(i),width15,height5,font(宋体,14),commandlambdanumi:[window.destroy(),open_order(num)])btn.grid(rowrow,columncol,padx15,pady15)# 设置按钮位置和间距# 管理者登录按钮manager_btnt.Button(window,text管理者登录,commandlambda:[window.destroy(),manager_login_window()],width20,height2,font(宋体,12))manager_btn.pack(pady15)# 减小pady值确保按钮可见window.mainloop()# 启动主界面循环# 启动程序if__name____main__:main_window()# 启动程序主界面2. order.py顾客点餐核心Pythonimporttkinterastfromtkinterimportmessageboxasinfoimportjsonimportos,datetime,subprocess,sysimportmain,shuju# 基本初始数据# 订单信息ordered_items[]total_price0.0current_desk_number未知桌号# 当前桌号默认为未知桌号# 初始化桌号函数definit_desk_number():从命令行参数获取并初始化桌号globalcurrent_desk_numberimportsysiflen(sys.argv)1:current_desk_numbersys.argv[1]# 类集合# 辣度类classLadu:def__init__(self,name):self.namenamedef__str__(self):returnself.name# 菜单类classDish:def__init__(self,name,price,category热菜,laduLadu(微辣),beizhu无):self.namename self.priceprice self.categorycategory self.laduladu self.beizhubeizhu# 菜单显示格式和__init__同级缩进defdisplay_in_menu(self):returnf{self.name}-{self.price}元 -{self.category}# 菜品字符串表示用于已选列表显示def__str__(self):returnf{self.name}-{self.ladu}- 备注{self.beizhu}-{self.price}元# 菜品库menu_items{}# 函数集合# 保存菜单函数defsave_menu_to_json():# 保存内容到菜单文件globalmenu json_filer./菜单.jsontry:menu_data[]fora,(dish_name,dish_object)inenumerate(menu_items.items(),1):menu_data.append({id:a,name:dish_object.name,price:dish_object.price,category:dish_object.category})withopen(json_file,w,encodingutf-8)asfile:json.dump(menu_data,file,ensure_asciiFalse,indent4)print(f保存了{len(menu_data)}菜品)exceptExceptionase:print(f保存失败原因为{str(e)})# 保存营业额函数defsave_sales_data():将当前订单保存为营业数据到JSON文件globalordered_items,total_price sales_file_pathr./营业数据.jsontry:# 获取当前时间nowdatetime.datetime.now()current_datenow.strftime(%Y%m%d)# YYYYMMDD格式的日期current_timenow.strftime(%Y-%m-%d %H:%M:%S)# 完整时间格式# 读取现有营业数据sales_data[]ifos.path.exists(sales_file_path):try:withopen(sales_file_path,r,encodingutf-8)asfile:file_contentfile.read().strip()iffile_content:sales_datajson.loads(file_content)exceptjson.JSONDecodeError:# 文件内容不是有效的JSON创建一个新的空列表sales_data[]# 生成订单编号当天时间编号today_orders0fororderinsales_data:if订单编号inorderandorder[订单编号].startswith(current_date):today_orders1order_numberf{current_date}{today_orders1:03d}# 生成订单编号# 准备订单详情order_details[]fordishinordered_items:order_details.append({菜品名:dish.name,辣度:str(dish.ladu),备注:dish.beizhu,价格:dish.price})# 创建新订单数据new_order{订单编号:order_number,时间:current_time,桌号:current_desk_number,# 使用当前桌号具体内容:order_details,总金额:total_price}# 添加新订单到营业数据sales_data.append(new_order)# 保存更新后的营业数据确保使用UTF-8编码withopen(sales_file_path,w,encodingutf-8,newline)asfile:json.dump(sales_data,file,ensure_asciiFalse,indent4,defaultstr)print(f营业数据保存成功{order_number})exceptExceptionase:print(f保存营业数据失败{str(e)})info.showerror(错误,f保存营业数据失败{str(e)})# 清空当前订单函数defclear_current_order():清空当前订单的所有菜品和总价globalordered_items,total_price ordered_items[]# 清空已点菜品列表total_price0.0# 清空总价selected_listbox.delete(0,end)# 清空列表框显示# 读取菜单函数defmenu():# 从json文件加载菜单数据并传唤为菜单globalmenu_items json_pathr./菜单.jsontry:withopen(json_path,r,encodingutf-8)asfile:menu_datajson.load(file)# 将json数据转换为dish对象字典menu_items{}foriteminmenu_data:dish_nameitem[name]dish_priceitem[price]dish_categoryitem.get(category,热菜)menu_items[dish_name]Dish(dish_name,dish_price,dish_category)print(f共打印了{len(menu_items)}个菜品)exceptFileNotFoundError:print(fJSON文件{json}为找到)# 备用方案menu_items{麻辣香锅:Dish(麻辣香锅,58,热菜),水煮鱼:Dish(水煮鱼,88,热菜),回锅肉:Dish(回锅肉,42,热菜),番茄炒蛋:Dish(番茄炒蛋,22,热菜),鱼香肉丝:Dish(鱼香肉丝,38,热菜),}save_menu_to_json()# 加菜函数defadd_dish(dish_object):加菜函数说明 点击下单后弹出备注窗口 功能如下 辣度选择 备注 取消下单 弹出辣度选择窗口让用户选择菜品的辣度和备注# 创建新的辣度选择窗口beizhu_windowt.Toplevel()beizhu_window.title(f选择{dish_object.name}的辣度)beizhu_window.geometry(300x250)# 固定窗口大小# 辣度选择单选按钮ladu_vart.StringVar(value微辣)# 默认微辣t.Label(beizhu_window,text选择辣度).pack(pady5)t.Radiobutton(beizhu_window,text清淡,variableladu_var,value清淡).pack()t.Radiobutton(beizhu_window,text微辣,variableladu_var,value微辣).pack()t.Radiobutton(beizhu_window,text中辣,variableladu_var,value中辣).pack()t.Radiobutton(beizhu_window,text爆辣,variableladu_var,value爆辣).pack()# 备注输入框t.Label(beizhu_window,text备注忌口等).pack(pady5)beizhu_vart.StringVar(value无)# 默认无备注beizhu_entryt.Entry(beizhu_window,textvariablebeizhu_var)beizhu_entry.pack()# 确认添加按钮函数defxiadan():确认添加菜品到订单selected_ladu_nameladu_var.get()# 获取选择的辣度名称selected_beizhubeizhu_var.get()# 获取备注# 创建辣度对象selected_laduLadu(selected_ladu_name)# 创建新的菜品对象包含用户选择的辣度和备注selected_dishDish(dish_object.name,dish_object.price,dish_object.category,selected_ladu,selected_beizhu)# 将菜品对象添加到订单ordered_items.append(selected_dish)globaltotal_price# 声明使用全局变量total_pricedish_object.price# 更新总价# 更新右侧已选菜品列表selected_listbox.insert(end,str(selected_dish))# 关闭辣度选择窗口beizhu_window.destroy()# 显示成功信息info.showinfo(提示,f{dish_object.name}已加入订单)# 返回主界面函数defback():返回主界面不添加菜品beizhu_window.destroy()# 创建按钮容器button_framet.Frame(beizhu_window)button_frame.pack(pady10)# 添加按钮t.Button(button_frame,text确认添加,commandxiadan).pack(sideleft,padx5)t.Button(button_frame,text返回,commandback).pack(sideleft,padx5)# 删菜函数defdelete_dish():删除选中的已点菜品# 获取选中菜品的索引selected_indexselected_listbox.curselection()ifnotselected_index:# 如果没有选中任何菜品则显示提示info.showwarning(提示,先选中要删除的菜品)returnindexselected_index[0]# 从订单中删除菜品对象并更新总价deleted_dishordered_items.pop(index)globaltotal_price total_price-deleted_dish.price# 更新总价# 从列表框显示中删除selected_listbox.delete(index)info.showinfo(提示,f已删除{deleted_dish.name})# 预览菜单函数defview_preview():显示当前订单的预览信息ifnotordered_items:# 如果没有点任何菜品则显示提示info.showwarning(提示,还没点任何菜品)return# 组装预览内容preview_content 订单预览 \nfornumber,dish_objectinenumerate(ordered_items,1):preview_contentf{number}.{dish_object.name}-{dish_object.ladu}- 备注{dish_object.beizhu}-{dish_object.price}元\npreview_contentf\n总价{total_price}元# 显示弹窗info.showinfo(订单预览,preview_content)# 下单函数defxiadan_dish():确认当前订单并保存营业数据ifnotordered_items:info.showwarning(提示,没点菜品不能下单)return# 组装订单信息order_content 下单成功 \nfornumber,dish_objectinenumerate(ordered_items,1):order_contentf{number}.{dish_object.name}-{dish_object.ladu}- 备注{dish_object.beizhu}-{dish_object.price}元\norder_contentf\n总价{total_price}元\n\n坐等上菜info.showinfo(下单成功,order_content)# 保存营业数据到JSON文件save_sales_data()# 清空当前订单clear_current_order()# 用户/加菜功能函数集合调用函数defuser_function_buttons():创建底部的功能按钮区域bottom_containert.Frame(order_window)# 创建按钮容器bottom_container.pack(pady20)# 放置容器# 删除按钮t.Button(bottom_container,text删除选中菜品,commanddelete_dish,width15).pack(sideleft,padx10)# 预览按钮t.Button(bottom_container,text查看订单预览,commandview_preview,width15).pack(sideleft,padx10)# 下单按钮t.Button(bottom_container,text确认下单,commandxiadan_dish,width15).pack(sideleft,padx10)# 返回主界面按钮t.Button(bottom_container,text返回主界面,commandlambda:[order_window.destroy(),main.main_window()],width15).pack(sideleft,padx10)# 加载菜单数据menu()# 初始化桌号init_desk_number()# 更新菜单函数defupdate_dish_list():更新菜品列表显示# 清空当前列表dish_listbox.delete(0,end)# 重新填充菜品列表fordish_objectinmenu_items.values():dish_listbox.insert(end,dish_object.display_in_menu())# 双击点餐函数defdouble_click_order(event):双击菜品列表触发点餐功能# 获取选中菜品的索引selected_indexdish_listbox.curselection()ifselected_index:indexselected_index[0]# 获取菜品项文本dish_itemdish_listbox.get(index)# 解析菜品名dish_namedish_item.split( - )[0]# 从菜单中获取菜品对象dish_objectmenu_items[dish_name]# 调用添加菜品函数传递菜品对象add_dish(dish_object)# 主窗口创建函数defcreate_order_window(desk_number未知桌号):创建并显示订单窗口 Args: desk_number: 桌号默认为未知桌号 globalcurrent_desk_number,order_window,dish_listbox,selected_listbox current_desk_numberdesk_number# 搭建界面 # 1. 创建订单窗口order_windowt.Tk()# 创建主窗口order_window.title(f大哥大饭店 - 桌号{current_desk_number})# 设置窗口标题包含桌号order_window.geometry(800x500)# 窗口大小适当增大以容纳新按钮# 2. 顶部欢迎信息welcome_labelt.Label(order_window,text欢迎来到大哥大饭店管理系统,font(宋体,14))welcome_label.pack(pady10)# 3. 中间区域左侧菜品表格 右侧已选列表middle_containert.Frame(order_window)# 创建中间容器middle_container.pack(fillboth,expandTrue,padx20)# 左侧菜品列表middle_containert.Frame(order_window)middle_container.pack(fillboth,expandTrue,padx20)# 左侧菜品列表使用Listbox与右侧已选列表保持一致格式dish_tablet.Frame(middle_container,bd1,reliefsolid)dish_table.pack(sideleft,fillboth,expandTrue,padx10)t.Label(dish_table,text菜品列表双击点餐,font(宋体,12)).pack(pady5)# 菜品列表框与右侧已选列表保持一致格式dish_listboxt.Listbox(dish_table,width30,height10)dish_listbox.pack(pady5,padx5)# 初始填充菜品列表update_dish_list()dish_listbox.bind(Double-Button-1,double_click_order)# 中间功能按钮区动态菜单功能 # 调用修改菜单数据函数 modify_dish() # 右侧已选菜品列表selected_containert.Frame(middle_container,bd1,reliefsolid)selected_container.pack(sideright,fillboth,expandTrue,padx10)t.Label(selected_container,text已选菜品,font(宋体,12)).pack(pady5)# 左侧已选菜品列表框selected_listboxt.Listbox(selected_container,width30,height10)selected_listbox.pack(pady5,padx5)# 启用用户功能按钮user_function_buttons()# 第四步运行程序 order_window.mainloop()# 启动主循环显示界面# 如果直接运行该文件则创建订单窗口if__name____main__:# 初始化桌号init_desk_number()# 创建订单窗口create_order_window(current_desk_number)3. guanli.py管理员管理Pythonimporttkinterastfromtkinterimportmessageboxasinfoimportjsonimportos,datetimeimportmain,shuju# 基本初始数据# 订单信息ordered_items[]total_price0.0#类集合#辣度类classLadu:def__init__(self,name):self.namenamedef__str__(self):returnself.name#菜单类classDish:def__init__(self,name,price,category热菜,laduLadu(微辣),beizhu无):self.namename self.priceprice self.categorycategory self.laduladu self.beizhubeizhu# 菜单显示格式和__init__同级缩进defdisplay_in_menu(self):returnf{self.name}-{self.price}元 -{self.category}# 菜品字符串表示用于已选列表显示def__str__(self):returnf{self.name}-{self.ladu}- 备注{self.beizhu}-{self.price}元# 菜品库menu_items{}# 函数集合#保存菜单函数defsave_menu_to_json():#保存内容到菜单文件globalmenu json_filer./菜单.jsontry:menu_data[]fora,(dish_name,dish_object)inenumerate(menu_items.items(),1):menu_data.append({id:a,name:dish_object.name,price:dish_object.price,category:dish_object.category})withopen(json_file,w,encodingutf-8)asfile:json.dump(menu_data,file,ensure_asciiFalse,indent4)print(f保存了{len(menu_data)}菜品)exceptExceptionase:print(f保存失败原因为{str(e)})# 保存营业额函数defsave_sales_data():将当前订单保存为营业数据到JSON文件globalordered_items,total_price sales_file_pathr./营业数据.jsontry:# 获取当前时间nowdatetime.datetime.now()current_datenow.strftime(%Y%m%d)# YYYYMMDD格式的日期current_timenow.strftime(%Y-%m-%d %H:%M:%S)# 完整时间格式# 读取现有营业数据sales_data[]ifos.path.exists(sales_file_path):try:withopen(sales_file_path,r,encodingutf-8)asfile:file_contentfile.read().strip()iffile_content:sales_datajson.loads(file_content)exceptjson.JSONDecodeError:# 文件内容不是有效的JSON创建一个新的空列表sales_data[]# 生成订单编号当天时间编号today_orders0fororderinsales_data:if订单编号inorderandorder[订单编号].startswith(current_date):today_orders1order_numberf{current_date}{today_orders1:03d}# 生成订单编号# 准备订单详情order_details[]fordishinordered_items:order_details.append({菜品名:dish.name,辣度:str(dish.ladu),备注:dish.beizhu,价格:dish.price})# 创建新订单数据new_order{订单编号:order_number,时间:current_time,桌号:未知桌号,# 管理系统订单设置默认桌号具体内容:order_details,总金额:total_price}# 添加新订单到营业数据sales_data.append(new_order)# 保存更新后的营业数据确保使用UTF-8编码withopen(sales_file_path,w,encodingutf-8,newline)asfile:json.dump(sales_data,file,ensure_asciiFalse,indent4,defaultstr)print(f营业数据保存成功{order_number})exceptExceptionase:print(f保存营业数据失败{str(e)})info.showerror(错误,f保存营业数据失败{str(e)})#清空当前订单函数defclear_current_order():清空当前订单的所有菜品和总价globalordered_items,total_price ordered_items[]# 清空已点菜品列表total_price0.0# 清空总价selected_listbox.delete(0,end)# 清空列表框显示# 读取菜单函数defmenu():#从json文件加载菜单数据并传唤为菜单globalmenu_items json_pathr./菜单.jsontry:withopen(json_path,r,encodingutf-8)asfile:menu_datajson.load(file)# 将json数据转换为dish对象字典menu_items{}foriteminmenu_data:dish_nameitem[name]dish_priceitem[price]dish_categoryitem.get(category,热菜)menu_items[dish_name]Dish(dish_name,dish_price,dish_category)print(f共打印了{len(menu_items)}个菜品)exceptFileNotFoundError:print(fJSON文件{json}为找到)# 备用方案menu_items{麻辣香锅:Dish(麻辣香锅,58,热菜),水煮鱼:Dish(水煮鱼,88,热菜),回锅肉:Dish(回锅肉,42,热菜),番茄炒蛋:Dish(番茄炒蛋,22,热菜),鱼香肉丝:Dish(鱼香肉丝,38,热菜),}save_menu_to_json()# 加菜函数defadd_dish(dish_object):加菜函数说明 点击下单后弹出备注窗口 功能如下 辣度选择 备注 取消下单 弹出辣度选择窗口让用户选择菜品的辣度和备注# 创建新的辣度选择窗口beizhu_windowt.Toplevel()beizhu_window.title(f选择{dish_object.name}的辣度)beizhu_window.geometry(300x250)# 固定窗口大小# 辣度选择单选按钮ladu_vart.StringVar(value微辣)# 默认微辣t.Label(beizhu_window,text选择辣度).pack(pady5)t.Radiobutton(beizhu_window,text清淡,variableladu_var,value清淡).pack()t.Radiobutton(beizhu_window,text微辣,variableladu_var,value微辣).pack()t.Radiobutton(beizhu_window,text中辣,variableladu_var,value中辣).pack()t.Radiobutton(beizhu_window,text爆辣,variableladu_var,value爆辣).pack()# 备注输入框t.Label(beizhu_window,text备注忌口等).pack(pady5)beizhu_vart.StringVar(value无)# 默认无备注beizhu_entryt.Entry(beizhu_window,textvariablebeizhu_var)beizhu_entry.pack()# 确认添加按钮函数defxiadan():确认添加菜品到订单selected_ladu_nameladu_var.get()# 获取选择的辣度名称selected_beizhubeizhu_var.get()# 获取备注# 创建辣度对象selected_laduLadu(selected_ladu_name)# 创建新的菜品对象包含用户选择的辣度和备注selected_dishDish(dish_object.name,dish_object.price,dish_object.category,selected_ladu,selected_beizhu)# 将菜品对象添加到订单ordered_items.append(selected_dish)globaltotal_price# 声明使用全局变量total_pricedish_object.price# 更新总价# 更新右侧已选菜品列表selected_listbox.insert(end,str(selected_dish))# 关闭辣度选择窗口beizhu_window.destroy()# 显示成功信息info.showinfo(提示,f{dish_object.name}已加入订单)# 返回主界面函数defback():返回主界面不添加菜品beizhu_window.destroy()# 创建按钮容器button_framet.Frame(beizhu_window)button_frame.pack(pady10)# 添加按钮t.Button(button_frame,text确认添加,commandxiadan).pack(sideleft,padx5)t.Button(button_frame,text返回,commandback).pack(sideleft,padx5)#删菜函数defdelete_dish():删除选中的已点菜品# 获取选中菜品的索引selected_indexselected_listbox.curselection()ifnotselected_index:# 如果没有选中任何菜品则显示提示info.showwarning(提示,先选中要删除的菜品)returnindexselected_index[0]# 从订单中删除菜品对象并更新总价deleted_dishordered_items.pop(index)globaltotal_price total_price-deleted_dish.price# 更新总价# 从列表框显示中删除selected_listbox.delete(index)info.showinfo(提示,f已删除{deleted_dish.name})# 预览菜单函数defview_preview():显示当前订单的预览信息ifnotordered_items:# 如果没有点任何菜品则显示提示info.showwarning(提示,还没点任何菜品)return# 组装预览内容preview_content 订单预览 \nfornumber,dish_objectinenumerate(ordered_items,1):preview_contentf{number}.{dish_object.name}-{dish_object.ladu}- 备注{dish_object.beizhu}-{dish_object.price}元\npreview_contentf\n总价{total_price}元# 显示弹窗info.showinfo(订单预览,preview_content)# 下单函数defxiadan_dish():确认当前订单并保存营业数据ifnotordered_items:info.showwarning(提示,没点菜品不能下单)return# 组装订单信息order_content 下单成功 \nfornumber,dish_objectinenumerate(ordered_items,1):order_contentf{number}.{dish_object.name}-{dish_object.ladu}- 备注{dish_object.beizhu}-{dish_object.price}元\norder_contentf\n总价{total_price}元\n\n坐等上菜info.showinfo(下单成功,order_content)# 保存营业数据到JSON文件save_sales_data()# 清空当前订单clear_current_order()# 用户/加菜功能函数集合调用函数defuser_function_buttons():创建底部的功能按钮区域bottom_containert.Frame(order_window)# 创建按钮容器bottom_container.pack(pady20)# 放置容器# 删除按钮t.Button(bottom_container,text删除选中菜品,commanddelete_dish,width15).pack(sideleft,padx10)# 预览按钮t.Button(bottom_container,text查看订单预览,commandview_preview,width15).pack(sideleft,padx10)# 下单按钮t.Button(bottom_container,text确认下单,commandxiadan_dish,width15).pack(sideleft,padx10)# 数据分析按钮t.Button(bottom_container,text数据分析,commandlambda:shuju.shuju_gui(order_window),width15).pack(sideleft,padx10)# 返回主界面按钮t.Button(bottom_container,text返回主界面,commandlambda:[order_window.destroy(),main.main_window()],width15).pack(sideleft,padx10)# 加载菜单数据menu()# 修改菜单数据函数管理功能defmodify_dish():菜单管理功能包括添加、修改、删除菜品# 添加新菜品defadd_new_dish():添加新菜品到菜单new_dish_windowt.Toplevel()new_dish_window.title(添加新菜品)new_dish_window.geometry(300x250)# 增加窗口高度以容纳品类选择t.Label(new_dish_window,text菜品名).pack(pady5)new_dish_namet.StringVar()t.Entry(new_dish_window,textvariablenew_dish_name).pack()t.Label(new_dish_window,text价格).pack(pady5)new_pricet.StringVar()t.Entry(new_dish_window,textvariablenew_price).pack()# 添加品类选择t.Label(new_dish_window,text品类).pack(pady5)new_categoryt.StringVar(value热菜)# 默认热菜category_options[热菜,凉菜,主食,饮料]category_dropdownt.OptionMenu(new_dish_window,new_category,*category_options)category_dropdown.pack()defconfirm_add_new_dish():确认添加新菜品dish_namenew_dish_name.get()# 获取菜品名pricenew_price.get()# 获取价格categorynew_category.get()# 获取品类ifnotdish_nameornotprice:info.showwarning(提示,请输入菜品名和价格)returntry:pricefloat(price)# 转换价格为浮点数menu_items[dish_name]Dish(dish_name,price,category)# 创建新菜品update_dish_list()# 更新菜品列表显示save_menu_to_json()# 保存到JSON文件new_dish_window.destroy()info.showinfo(提示,新菜品添加成功)exceptValueError:info.showwarning(提示,价格必须是数字)defback():返回菜单管理界面new_dish_window.destroy()button_framet.Frame(new_dish_window)button_frame.pack(pady10)t.Button(button_frame,text确认添加,commandconfirm_add_new_dish,width12).pack(sideleft,padx5)t.Button(button_frame,text返回,commandback,width12).pack(sideleft,padx5)# 修改菜品价格defmodify_dish_price():修改现有菜品的价格modify_windowt.Toplevel()modify_window.title(修改菜品价格)modify_window.geometry(300x200)t.Label(modify_window,text选择菜品).pack(pady5)selected_menu_itemt.StringVar()dish_dropdownt.OptionMenu(modify_window,selected_menu_item,*menu_items.keys())dish_dropdown.pack()t.Label(modify_window,text新价格).pack(pady5)new_pricet.StringVar()t.Entry(modify_window,textvariablenew_price).pack()defconfirm_modify_price():确认修改菜品价格dish_nameselected_menu_item.get()# 获取选择的菜品pricenew_price.get()# 获取新价格ifnotdish_nameornotprice:info.showwarning(提示,请选择菜品并输入新价格)returntry:pricefloat(price)# 转换价格为浮点数# 更新菜品对象价格dish_objectmenu_items[dish_name]dish_object.priceprice update_dish_list()# 更新菜品列表显示save_menu_to_json()# 保存到JSON文件modify_window.destroy()info.showinfo(提示,价格修改成功)exceptValueError:info.showwarning(提示,价格必须是数字)defback():返回菜单管理界面modify_window.destroy()button_framet.Frame(modify_window)button_frame.pack(pady10)t.Button(button_frame,text确认修改,commandconfirm_modify_price,width12).pack(sideleft,padx5)t.Button(button_frame,text返回,commandback,width12).pack(sideleft,padx5)# 从菜单中删除菜品defdelete_dish_from_menu():从菜单中删除菜品delete_windowt.Toplevel()delete_window.title(删除菜品)delete_window.geometry(300x150)t.Label(delete_window,text选择要删除的菜品).pack(pady5)selected_menu_itemt.StringVar()dish_dropdownt.OptionMenu(delete_window,selected_menu_item,*menu_items.keys())dish_dropdown.pack()defconfirm_delete():确认删除菜品dish_nameselected_menu_item.get()# 获取要删除的菜品ifnotdish_name:info.showwarning(提示,请选择要删除的菜品)returnifinfo.askyesno(确认,f确定要删除{dish_name}吗):delmenu_items[dish_name]# 删除菜品update_dish_list()# 更新菜品列表显示save_menu_to_json()# 保存到JSON文件delete_window.destroy()info.showinfo(提示,菜品删除成功)defback():返回菜单管理界面delete_window.destroy()button_framet.Frame(delete_window)button_frame.pack(pady10)t.Button(button_frame,text确认删除,commandconfirm_delete,width12).pack(sideleft,padx5)t.Button(button_frame,text返回,commandback,width12).pack(sideleft,padx5)# 创建功能按钮容器function_button_areat.Frame(dish_table)function_button_area.pack(pady10)# 添加按钮t.Button(function_button_area,text添加新菜品,commandadd_new_dish).pack(sideleft,padx5)t.Button(function_button_area,text修改菜品价格,commandmodify_dish_price).pack(sideleft,padx5)t.Button(function_button_area,text删除菜品,commanddelete_dish_from_menu).pack(sideleft,padx5)# 更新菜单函数defupdate_dish_list():更新菜品列表显示# 清空当前列表dish_listbox.delete(0,end)# 重新填充菜品列表fordish_objectinmenu_items.values():dish_listbox.insert(end,dish_object.display_in_menu())#双击点餐函数defdouble_click_order(event):双击菜品列表触发点餐功能# 获取选中菜品的索引selected_indexdish_listbox.curselection()ifselected_index:indexselected_index[0]# 获取菜品项文本dish_itemdish_listbox.get(index)# 解析菜品名dish_namedish_item.split( - )[0]# 从菜单中获取菜品对象dish_objectmenu_items[dish_name]# 调用添加菜品函数传递菜品对象add_dish(dish_object)# 主窗口创建函数defcreate_guanli_window():创建并显示管理系统窗口globalorder_window,dish_listbox,selected_listbox,dish_table# 搭建界面 # 1. 创建订单窗口order_windowt.Tk()# 创建主窗口order_window.title(大哥大饭店)# 设置窗口标题order_window.geometry(800x500)# 窗口大小适当增大以容纳新按钮# 2. 顶部欢迎信息welcome_labelt.Label(order_window,text欢迎来到大哥大饭店管理系统,font(宋体,14))welcome_label.pack(pady10)# 3. 中间区域左侧菜品表格 右侧已选列表middle_containert.Frame(order_window)# 创建中间容器middle_container.pack(fillboth,expandTrue,padx20)# 左侧菜品列表middle_containert.Frame(order_window)middle_container.pack(fillboth,expandTrue,padx20)# 左侧菜品列表使用Listbox与右侧已选列表保持一致格式dish_tablet.Frame(middle_container,bd1,reliefsolid)dish_table.pack(sideleft,fillboth,expandTrue,padx10)t.Label(dish_table,text菜品列表双击点餐,font(宋体,12)).pack(pady5)# 菜品列表框与右侧已选列表保持一致格式dish_listboxt.Listbox(dish_table,width30,height10)dish_listbox.pack(pady5,padx5)# 更新菜品列表的函数可调用以刷新显示# 初始填充菜品列表update_dish_list()dish_listbox.bind(Double-Button-1,double_click_order)# 中间功能按钮区动态菜单功能 # 调用修改菜单数据函数modify_dish()# 右侧已选菜品列表selected_containert.Frame(middle_container,bd1,reliefsolid)selected_container.pack(sideright,fillboth,expandTrue,padx10)t.Label(selected_container,text已选菜品,font(宋体,12)).pack(pady5)# 左侧已选菜品列表框selected_listboxt.Listbox(selected_container,width30,height10)selected_listbox.pack(pady5,padx5)# 启用用户功能按钮user_function_buttons()# 第四步运行程序 order_window.mainloop()# 启动主循环显示界面# 如果直接运行该文件则创建管理系统窗口if__name____main__:create_guanli_window()4. shuju.py数据统计与可视化Pythonimportjsonimportosimportdatetimeimporttkinterastfromtkinterimportmessageboxasinfo,ttkimportmatplotlib.pyplotaspltfrommatplotlib.backends.backend_tkaggimportFigureCanvasTkAgg# 设置matplotlib支持中文plt.rcParams[font.sans-serif][SimHei]# 使用黑体字体支持中文显示plt.rcParams[axes.unicode_minus]False# 负号显示#读取文件数据defdu_qu_shuju():读取文件数据 返回值 list:包含所有订单数据的列表如果失败返回空列表 #读取当前目录以绝对路径获取文件数据dangqian_diros.path.dirname(os.path.abspath(__file__))shujuos.path.join(dangqian_dir,营业数据.json)yingye_data[]try:ifos.path.exists(shuju):withopen(shuju,r,encodingutf-8)asfile:contentfile.read().strip()ifcontent:yingye_datajson.loads(content)returnyingye_dataexceptExceptionase:info.showerror(错误,f读取数据失败)return[]#小时函数defhour_sales(data,riqi):按小时统计指定日期的销售额 参数: data: 包含所有订单数据的列表 riqi: 要统计的日期格式为YYYY-MM-DD 命名 hour_sales: 符合条件的日期 order_time: 订单时间 返回值: dict: 包含每个小时销售额的字典键为小时如00-23值为销售额 hour_sales{}# 遍历所有订单fororderindata:try:# 查找关键字存储起来time_keyNoneforkeyinorder:if时间inkey:time_keykeybreak# 修正没有找到时间字段才跳过iftime_keyisNone:continue# 解析订单时间order_timedatetime.datetime.strptime(order[time_key],%Y-%m-%d %H:%M:%S)# 获取订单日期order_dateorder_time.strftime(%Y-%m-%d)# 只统计选择的日期iforder_date!riqi:continue# 提取订单时间的时段hourorder_time.strftime(%H)# 修正查找总金额字段逻辑total_keyNoneforkeyinorder:if总金额inkey:total_keykeybreak# 没有总金额字段则跳过iftotal_keyisNone:continue# 获取订单金额并转换为数字hour_qianfloat(order[total_key])# 确保金额是数字类型# 小时销售额累加逻辑ifhourinhour_sales:hour_sales[hour]hour_qianelse:hour_sales[hour]hour_qian# 出错则跳到下一个订单exceptExceptionase:continue# 确保所有小时00-23都有数据没有销售额的小时设置为0forhourinrange(24):hour_strf{hour:02d}ifhour_strnotinhour_sales:hour_sales[hour_str]0.0# 按小时排序并返回结果returndict(sorted(hour_sales.items()))#天数函数defday_sales(data):日统计表 参数 data订单数据内容 返回值 weekly_sales: 包含每天销售额的字典以周为一个范围 weekdays[周一,周二,周三,周四,周五,周六,周日]#初始化每周各天销售额为0weekly_sales{day:0fordayinweekdays}# 遍历订单获取数据fororderindata:try:time_keyNoneforkeyinorder:if时间inkey:time_keykeybreakiftime_keyisNone:continue# 解析订单时间并通过datetime库分析为周几order_timedatetime.datetime.strptime(order[time_key],%Y-%m-%d %H:%M:%S)# 获取星期几的索引0一6日weekday_indexorder_time.weekday()# 根据索引获取星期几的中文名称weekday_nameweekdays[weekday_index]total_keyNoneforkeyinorder:if总金额inkey:total_keykeybreakiftotal_keyisNone:continue# 获取订单金额为浮点数total_amountfloat(order[total_key])# 累加每周各天总金额weekly_sales[weekday_name]total_amountexceptExceptionase:print(该订单出错跳过处理下一单)continuereturnweekly_sales#画图函数defcreate_tubiao(data,title,x_label,y_label,horizontalFalse):创建条形图 参数: data: 要显示的数据字典 title: 图表标题 x_label: X轴标签 y_label: Y轴标签 horizontal: 是否创建水平条形图默认为False垂直条形图 返回值: matplotlib.figure.Figure: 创建的图表对象 # 从数据字典中提取标签和数值labelslist(data.keys())amountslist(data.values())# 根据是否为水平条形图和数据量调整图表大小使其更紧凑ifhorizontalandlen(labels)10:# 水平条形图且数据量较多时增加高度以便完整显示fig,axplt.subplots(figsize(10,8))else:# 默认图表大小fig,axplt.subplots(figsize(8,5))# 创建条形图ifhorizontal:# 创建水平条形图barsax.barh(labels,amounts,colorlightblue)else:# 创建垂直条形图barsax.bar(labels,amounts,colorlightgreen)# 设置图表标题和坐标轴标签ax.set_title(title,fontsize14)ax.set_xlabel(x_label,fontsize12)ax.set_ylabel(y_label,fontsize12)# 在条形图上显示数值forbarinbars:ifhorizontal:# 水平条形图数值显示在条形右侧widthbar.get_width()ax.text(width1,bar.get_y()bar.get_height()/2,f{width:.2f},vacenter,fontsize10)else:# 垂直条形图数值显示在条形顶部heightbar.get_height()ax.text(bar.get_x()bar.get_width()/2,height1,f{height:.2f},hacenter,fontsize10)# 添加网格线ax.grid(axisxifhorizontalelsey,linestyle--,alpha0.7)plt.tight_layout()# 自动调整图表布局returnfig#数据窗口defshuju_gui(parentNone): 参数parent:父窗口如果为None则创建一个新的根窗口 ifparentisNone:roott.Tk()else:roott.Toplevel(parent)root.title(营业数据分析)root.geometry(1200x800)root.resizable(widthTrue,heightTrue)sales_datadu_qu_shuju()# 获取所有可用日期all_datesset()fororderinsales_data:try:# 找到时间字段time_keyNoneforkeyinorder:if时间inkeyor时inkey:time_keykeybreak# 如果有时间字段提取日期iftime_key:order_timedatetime.datetime.strptime(order[time_key],%Y-%m-%d %H:%M:%S)all_dates.add(order_time.strftime(%Y-%m-%d))except:# 如果处理出错跳过此订单continue# 倒序排序方便查看近期数据daoxun_datessorted(list(all_dates),reverseTrue)# 选择最新的日期作为默认值mongren_datedaoxun_dates[0]ifdaoxun_dateselsecontrol_framettk.LabelFrame(root,text数据选择,padding10)control_frame.pack(fillt.X,padx10,pady10)ttk.Label(control_frame,text查看方式).pack(sidet.LEFT,padx10,pady10)view_typet.StringVar(value按天)defupdate_tubiao():更新图表ifview_type.get()按天:# 按天查看 - 显示每小时销售额datedate_combo.get()ifnotdate:info.showinfo(提示,请选择日期)return# 统计该日期的每小时销售额hourly_saleshour_sales(sales_data,date)titlef{date}每小时销售额# 创建水平条形图figcreate_tubiao(hourly_sales,title,销售额元,小时,horizontalTrue)# 计算并更新统计信息totalsum(hourly_sales.values())# 总销售额max_hourmax(hourly_sales,keyhourly_sales.get)# 销售额最高的小时max_saleshourly_sales[max_hour]# 最高销售额else:# 按星期查看 - 显示每周各天销售额# 统计每周各天的销售额weekly_salesday_sales(sales_data)title每周各天销售额统计# 创建垂直条形图figcreate_tubiao(weekly_sales,title,星期,销售额元,horizontalFalse)# 计算并更新统计信息totalsum(weekly_sales.values())# 总销售额max_daymax(weekly_sales,keyweekly_sales.get)# 销售额最高的星期max_salesweekly_sales[max_day]# 最高销售额# 更新图表# 首先清除旧的图表显示forwidgetinchart_frame.winfo_children():widget.destroy()# 创建新的canvas并显示canvasFigureCanvasTkAgg(fig,masterchart_frame)canvas.draw()canvas.get_tk_widget().pack(fillt.BOTH,expandTrue,padx10,pady10)# 更新统计信息stats_label.config(textf总销售额{total:.2f}元 | 最高{max_sales:.2f}元)# 按天查看按钮look_day_btnttk.Radiobutton(control_frame,text按天,variableview_type,value按天,commandupdate_tubiao)look_day_btn.pack(sidet.LEFT,padx5)# 按星期查看按钮look_week_btnttk.Radiobutton(control_frame,text按星期,variableview_type,value按星期,commandupdate_tubiao)look_week_btn.pack(sidet.LEFT,padx5)# 日期选择下拉框ttk.Label(control_frame,text日期).pack(sidet.LEFT,padx5)date_combottk.Combobox(control_frame,valuesdaoxun_dates,statereadonly,width12)date_combo.pack(sidet.LEFT,padx5)# 设置默认选中最新的日期ifdaoxun_dates:date_combo.set(daoxun_dates[0])# 刷新按钮refresh_btnttk.Button(control_frame,text刷新,commandupdate_tubiao)refresh_btn.pack(sidet.RIGHT,padx10)# 图表显示区域chart_framettk.Frame(root)chart_frame.pack(fillt.BOTH,expandTrue,padx10,pady10)# 创建初始图表ifdaoxun_dates:# 有数据时显示最新日期的每小时销售额hourly_saleshour_sales(sales_data,daoxun_dates[0])titlef{daoxun_dates[0]}每小时销售额figcreate_tubiao(hourly_sales,title,销售额元,小时,horizontalTrue)totalsum(hourly_sales.values())max_hourmax(hourly_sales,keyhourly_sales.get)max_saleshourly_sales[max_hour]else:# 无数据时显示提示信息fig,axplt.subplots(figsize(10,6))ax.set_title(暂无数据,fontsize16)total0max_sales0# 嵌入图表到界面canvasFigureCanvasTkAgg(fig,masterchart_frame)canvas.draw()canvas.get_tk_widget().pack(fillt.BOTH,expandTrue,padx10,pady10)# 统计信息显示stats_labelttk.Label(root,textf总销售额{total:.2f}元 | 最高{max_sales:.2f}元,font(Arial,12))stats_label.pack(fillt.X,padx10,pady10)# 增加底部边距使界面更美观# 启动主循环root.mainloop()if__name____main__:shuju_gui()5. 数据文件示例菜单.jsonJSON[{id:1,name:宫保鸡丁,price:28,category:热菜},{id:2,name:鱼香肉丝,price:25,category:热菜},// ... 共19道菜]用户信息.json默认管理员账号JSON[{账号:1,密码:123,角色:管理者},{账号:123,密码:456,角色:管理者}]营业数据.json订单记录示例JSON[{订单编号:20251212001,时间:2025-12-12 10:30:00,桌号:1,具体内容:[...],总金额:53.0}// ... 更多订单]运行方式直接双击 main.py 即可启动。首次运行会自动创建默认数据文件。总结这个项目虽然不大但几乎涵盖了 Tkinter 开发的所有核心知识点窗口与控件布局事件绑定双击、按钮模块间传参与跳转JSON 文件读写持久化Matplotlib 嵌入 GUI 实现动态图表面向对象封装Dish、Ladu 类通过这个项目我对 Python 桌面应用开发有了更深的理解也体会到模块化设计和异常处理的重要性。项目还有很多可扩展空间比如完善管理员菜品增删改界面加入打印小票功能引入 SQLite 数据库开发网络版支持多台平板同时点餐引用Tkinter的ttk进行美化喜欢的话欢迎 Star 或 Fork后续有更新会继续分享完整源码下载直接复制以上所有文件到同一文件夹即可运行。 如果有任何问题欢迎在评论区交流
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

学生做家教网站一个空间两个wordpress

测试驱动的基础设施‌ 在云原生成为主流的今天,Kubernetes (K8s) 已成为应用部署与运维的事实标准。对于软件测试从业者而言,测试活动的前沿已从单一应用扩展到包含编排、调度、网络、存储在内的整个动态基础设施层。传统的在静态环境中执行测试用例的模…

张小明 2026/1/7 4:19:41 网站建设

怎么做谷歌收录的网站云南网直播平台

常听到很多人不知道学习网络安全能做什么,发展前景好吗?今天我就在这里给大家介绍一下。网络安全作为目前比较火的朝阳行业,人才缺口非常大 先说结论,目前网络安全的前景还是很不错的 作为一个有丰富 Web 安全攻防、渗透领域老工…

张小明 2026/1/8 9:32:10 网站建设

公司做网站费用浙江省特种作业证查询官网

第一章:Open-AutoGLM模型压缩量化概述在大规模语言模型(LLM)日益普及的背景下,Open-AutoGLM 作为一种高效、可扩展的自动化模型压缩框架,致力于解决模型部署中的资源瓶颈问题。该框架专注于 GLM 系列模型的量化与压缩优…

张小明 2026/1/8 9:57:37 网站建设

个体工商户经营范围做网站广州动画制作公司

构建私有RAG知识库的完整流程(本地运行,隐私专有模型)目标:用本地LLM(如Ollama运行的开源模型)加载你的Markdown知识库,实现快速查询。预处理:PDF → Markdown(如上&…

张小明 2026/1/8 5:16:52 网站建设

做外贸到那个网站罗湖专业做网站公司

第一章:ZGC分代模式配置参数概述ZGC(Z Garbage Collector)是JDK 11引入的低延迟垃圾收集器,旨在实现毫秒级停顿时间的同时支持TB级堆内存。自JDK 17起,ZGC引入了分代模式(Generational ZGC)&…

张小明 2026/1/9 10:19:03 网站建设

电商网站设计与开发河南郑州app建设网站

如何让测试成为团队通用语言?在领域驱动设计的模块化单体架构中,我们常常陷入这样的困境:新成员需要数周才能理解复杂的业务规则,代码评审变成表面流程,技术债务在不知不觉中积累。这些痛点的根源在于,代码…

张小明 2026/1/8 15:30:38 网站建设