Tkinter Treeview借书记录绑定用户名及还书页展示KeyError解决
Tkinter图书管理系统用户借书绑定功能实现方案
现有问题
你遇到的KeyError和渲染异常主要来自3个核心错误:
- 临时创建的
borrow_dictionary仅在当前还书页生命周期有效,无法存储历史借阅数据,当用户没有历史借书记录、或是切换页面/重启程序后,读取不存在的用户名key就会抛出KeyError - 全局变量
checkout_ids是所有用户共用的,多用户场景下会出现借阅数据串用的问题 - 还书页Treeview渲染逻辑错误:一是把借阅ID遍历循环嵌套在了表头遍历循环内,会重复渲染数据;二是把数据插入到了借书页的
self.checkout_tree组件,而非当前还书页的self.return_book_tree组件
实现方案
1. 新增借阅关系持久化存储
不要用临时字典存借阅关系,单独新增borrow_records.csv存储所有借阅记录,字段如下:username,book_id,borrow_time,is_returned
每次用户点击确认借书按钮时,将当前登录用户名self.name_login.get()、选中的所有图书ID、当前时间、is_returned=0写入该csv文件即可。
2. 修复还书页加载逻辑
进还书页时,先从borrow_records.csv过滤出当前登录用户未归还的所有图书ID,再匹配图书表数据渲染到Treeview即可,示例修复代码如下:
import pandas as pd def return_book_page(self): self.borrow_or_return_page.destroy() return_page = Tk() return_page.title("Return page") return_page.config(padx=20,pady=20,bg=WHITE) # 界面标题、按钮等基础组件初始化逻辑和原有逻辑一致,此处省略 self.return_book_tree = ttk.Treeview() self.build_df = self.books_data.copy() self.return_book_tree["column"] = list(self.books_data.columns) self.return_book_tree["show"] = "headings" vsb = ttk.Scrollbar(orient="vertical", command=self.return_book_tree.yview()) vsb.grid(column=8, row=1, sticky="ns") self.return_book_tree.configure(yscrollcommand=vsb.set) # 读取借阅记录过滤当前用户未归还的图书 current_user = self.name_login.get().strip() borrow_records = pd.read_csv("borrow_records.csv") # 避免KeyError:不存在对应用户的借阅记录时返回空列表 user_unreturned_books = borrow_records[ (borrow_records["username"] == current_user) & (borrow_records["is_returned"] == 0) ]["book_id"].tolist() # 渲染表头(和遍历借阅ID逻辑拆分,避免重复渲染) for column in self.return_book_tree['column']: self.return_book_tree.heading(column, text=column) # 渲染借阅图书数据 for book_id in user_unreturned_books: build_df = self.build_df[self.build_df.IDENTIFICATION_NO == book_id] df_rows = build_df.to_numpy().tolist() for row in df_rows: # 修复插入组件错误,插入到当前还书的Treeview self.return_book_tree.insert("", "end", values=row) self.return_book_tree.grid(column=0, row=1, columnspan=8) return_page.mainloop()
3. 轻量优化方案
如果不想单独存借阅表,也可以直接在原有的图书表中新增borrow_user字段,用户借书时将对应用户名写入该字段,还书时清空,还书页直接过滤borrow_user == 当前用户名的图书即可,逻辑更简单。
内容的提问来源于stack exchange,提问作者Noahwaaa
相关产品推荐
相关产品推荐

