790 字
4 分钟
Python记账本
Python记账本
一个基于PySimpleGUI图形界面开发库写的记账本 使用时会在程序目录下生成一个data.txt文件用于存放数据 能简单的实现账单项目的录入及删除 内置导出Excel文件功能,可自定义导出路径并以导出时间命名
import jsonimport datetimeimport PySimpleGUI as sgimport pandas as pdimport osimport xlwt# import openpyxl
#读取数据def read_data(): try: with open(r"data.txt", "r") as f: json_data=f.read() datalist=json.loads(json_data)
return datalist except: return []#当文本里面没有数据时返回空列表
#写入数据def write_data(datalist): with open(r"data.txt", "w") as f: f.write(json.dumps(datalist, ensure_ascii=False))#防止改变中文编码格式
#显示数据def show_data(): try: data = read_data() datalist = [] for i in data: if i["分类"] == "支出": data_list = [i["时间"], i["项目"], i["金额"] * -1, i["分类"]] datalist.append(data_list) else: data_list = [i["时间"], i["项目"], i["金额"], i["分类"]] datalist.append(data_list) return datalist except: return []
#总收入支出 1为收入0为支出def amount_sum(cla): try: data = read_data() sum = 0 if cla == 1: for i in data: if i["分类"] == "收入": sum += i["金额"] if cla == 0: for i in data: if i["分类"] == "支出": sum += i["金额"] return sum except: return 0#当文本里面没有数据时返回0
#添加数据def add_data(project, amount, cla): datalist=read_data() time=datetime.datetime.now().strftime("%Y/%m/%d") data={"时间": time, "项目": project, "金额": amount, "分类": cla} datalist.append(data) write_data(datalist) sg.popup_auto_close('项目录入成功') # 弹窗
#删除数据def delete_data(index): datalist=read_data() del datalist[index] write_data(datalist) sg.popup_auto_close('删除成功')
#导出Excel文件def export(path): with open(r"data.txt", "r") as f: data=f.read() f.close() with open(r"data.json", "w", encoding='utf-8') as f: f.write(data) f.close() json_data=pd.read_json(r"data.json") json_data.to_excel(fr'{path}/{datetime.datetime.now().strftime("%Y%m%d")}.xls') os.remove(r"data.json") sg.popup("导出成功")
if __name__ == '__main__': List=show_data() #图形界面布局列表 sg.theme('LightBrown') layout=[ [sg.T("账目列表:")]+[sg.B("导出Excel文件", key="-export-", pad=((390, 0), (0, 0)))], [sg.Table(List, headings=["时间", "项目", "金额", "分类"], key="-show_table-", justification="c", auto_size_columns=False, def_col_width=15,)], [sg.T(f"总收入{amount_sum(1)}元 总支出{amount_sum(0)}元 结余:{amount_sum(1)-amount_sum(0)}元", key="-show_data-")], [sg.T("账单项目:"), sg.In(key="-project-")], [sg.T("账单金额:"), sg.In(key="-amount-")], [sg.T("项目分类:")] + [sg.Radio(i, group_id=1, key=i) for i in ["收入", "支出"]],#单选框 [sg.B("提交项目", key="-submit-")]+[sg.B("删除项目", key="-remove-", pad=((430, 0), (0, 0)))]
]
window=sg.Window("记账本", layout, font='宋体 13')
while True: event, values =window.read()#获取用户事件 if event=="-submit-":#用户触发提交数据
#判断用户是否输入完整数据 if values["-project-"]=='' or values["-amount-"]=='' or (values["收入"]==False and values["支出"]==False): sg.popup("请填写完整的数据") continue #判断用户输入金额是否为数字 if not str.isdigit(values["-amount-"]): sg.popup("请输入正确的金额") continue # 获取输入框中的值 project=values["-project-"] amount=float(values["-amount-"])
for k, v in values.items(): if v == True: cla=k add_data(project, amount, cla) List=show_data() text=f"总收入{amount_sum(1)}元 总支出{amount_sum(0)}元 结余:{amount_sum(1)-amount_sum(0)}元" window["-show_table-"].update(values=List) window["-show_data-"].update(value=text) #清空输入栏 window["-project-"].update(value="") window["-amount-"].update(value="") window["收入"].ResetGroup()
if event=="-remove-":#用户触发删除数据 #判断用户是否选中数据 if values["-show_table-"]: #确认删除弹窗 confirm = sg.popup_ok_cancel("确认删除选中的项目") if confirm == "OK": delete_data(values["-show_table-"][0])#删除数据 #更新表格 List = show_data() text = f"总收入{amount_sum(1)}元 总支出{amount_sum(0)}元 结余:{amount_sum(1) - amount_sum(0)}元" window["-show_table-"].update(values=List) window["-show_data-"].update(value=text) else: sg.popup("请选中一个项目")
if event=="-export-":#导出Excel文件 path=sg.popup_get_folder("保存路径:")
if path =='':#判断路径是否为空 sg.popup("请选择正确的路径") continue elif path is None:#防止用户因取消路径选择而关闭程序 continue else: export(path)
if event in (None, 'Exit'): break window.close()