Library图书馆应用拓展12-显示登录界面和主界面bugfix
前面的版本有bug,登录界面和主窗口还是会同时显示,更新一下
'''
ver14.py: 登录窗口和主窗口分别显示,前面ver12 ver13 没有解决这个问题
'''
import json
import tkinter as tk
from tkinter import messagebox, simpledialog
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
self.is_checked_out = False
def display_info(self):
status = "已借出" if self.is_checked_out else "可借阅"
return f"《{self.title}》 - 作者: {self.author} - 状态: {status}"
def check_out(self):
self.is_checked_out = True
def check_in(self):
self.is_checked_out = False
class User:
def __init__(self, username, password):
self.username = username
self.password = password
self.borrowed_books = []
def borrow_book(self, book):
if not book.is_checked_out:
book.check_out()
self.borrowed_books.append(book)
return f"借阅成功:《{book.title}》"
else:
return "抱歉,这本书已经被借出了。"
def return_book(self, book):
if book in self.borrowed_books:
book.check_in()
self.borrowed_books.remove(book)
return f"归还成功:《{book.title}》"
else:
return "这本书没有被这位用户借阅。"
class LoginApp:
def __init__(self, root, library_app):
self.root = root
self.root.title("用户登录")
self.library_app = library_app
self.library_app.root.withdraw() ## key fix: 确保主窗口在登录之前不会显示
# 创建 GUI 元素
self.label = tk.Label(root, text="用户登录", font=("Helvetica", 16))
self.label.pack(pady=10)
self.username_label = tk.Label(root, text="用户名:")
self.username_label.pack()
self.username_entry = tk.Entry(root)
self.username_entry.pack(pady=5)
self.password_label = tk.Label(root, text="密码:")
self.password_label.pack()
self.password_entry = tk.Entry(root, show="*")
self.password_entry.pack(pady=10)
self.login_button = tk.Button(root, text="登录", command=self.login)
self.login_button.pack(pady=5)
self.register_button = tk.Button(root, text="注册", command=self.register)
self.register_button.pack(pady=5)
root.protocol("WM_DELETE_WINDOW", self.on_closing)
def on_closing(self):
# 保存数据并关闭窗口
print(f"close login window...")
self.root.destroy()
self.library_app.root.destroy()
def login(self):
username = self.username_entry.get()
password = self.password_entry.get()
user = self.library_app.library.find_user(username, password)
if user:
# 关闭登录窗口
#self.root.destroy()
self.root.withdraw()
# 显示主窗口
self.library_app.root.deiconify()
self.library_app.show_main_interface(user)
else:
messagebox.showwarning("登录失败", "用户名或密码错误。")
def register(self):
username = self.username_entry.get()
password = self.password_entry.get()
if not self.library_app.library.is_username_taken(username):
new_user = User(username, password)
self.library_app.library.users.append(new_user)
messagebox.showinfo("注册成功", "注册成功,请使用新账户登录。")
else:
messagebox.showwarning("注册失败", "用户名已被使用,请选择其他用户名。")
class LibraryApp:
def __init__(self, root):
self.root = root
self.root.title("图书馆管理系统")
self.library = Library()
# 初始化用户登录界面
self.login_root = tk.Toplevel(root)
self.login_app = LoginApp(self.login_root, self)
# 关闭窗口时触发保存数据操作
root.protocol("WM_DELETE_WINDOW", self.on_closing)
self.is_init = False
def show_main_interface(self, user):
#self.main_interface = tk.Toplevel(self.root)
#self.main_interface.title("主界面")
# 创建 GUI 元素
if self.is_init:
return
self.is_init = True
self.label = tk.Label(self.root, text=f"欢迎,{user.username}!", font=("Helvetica", 16))
self.label.pack(pady=10)
self.listbox = tk.Listbox(self.root, selectmode=tk.SINGLE, font=("Helvetica", 12), height=10, width=50)
self.listbox.pack(pady=10)
self.borrow_button = tk.Button(self.root, text="借阅图书", command=self.borrow_book)
self.borrow_button.pack(pady=5)
self.return_button = tk.Button(self.root, text="归还图书", command=self.return_book)
self.return_button.pack(pady=5)
self.add_book_button = tk.Button(self.root, text="添加图书", command=self.add_book)
self.add_book_button.pack(pady=5)
# 在主界面显示图书列表
self.refresh_books_list()
def refresh_books_list(self):
self.listbox.delete(0, tk.END)
for book in self.library.books:
self.listbox.insert(tk.END, book.display_info())
def borrow_book(self):
selected_index = self.listbox.curselection()
if selected_index:
selected_book = self.library.books[selected_index[0]]
message = self.library.current_user.borrow_book(selected_book)
messagebox.showinfo("借阅图书", message)
self.refresh_books_list()
else:
messagebox.showwarning("借阅图书", "请选择要借阅的图书。")
def return_book(self):
selected_index = self.listbox.curselection()
if selected_index:
selected_book = self.library.books[selected_index[0]]
message = self.library.current_user.return_book(selected_book)
messagebox.showinfo("归还图书", message)
self.refresh_books_list()
else:
messagebox.showwarning("归还图书", "请选择要归还的图书。")
def add_book(self):
title_author = simpledialog.askstring("添加图书", "请输入书名和作者(用逗号分隔):")
if title_author:
title, author = map(str.strip, title_author.split(','))
new_book = Book(title, author)
self.library.books.append(new_book)
messagebox.showinfo("添加图书", f"《{title}》已成功添加到图书馆。")
self.refresh_books_list()
def on_closing(self):
# 保存数据并关闭窗口
print(f"close main window...")
self.library.save_data_to_files()
#self.root.destroy()
self.root.withdraw()
self.login_root.deiconify()
class Library:
def __init__(self):
self.books = []
self.users = []
self.current_user = None
# 从文件加载图书信息
self.load_books_from_file()
# 从文件加载用户信息
self.load_users_from_file()
def load_books_from_file(self):
try:
with open("books.json", "r") as file:
books_data = json.load(file)
for book_data in books_data:
book = Book(book_data["title"], book_data["author"])
book.is_checked_out = book_data["is_checked_out"]
self.books.append(book)
except FileNotFoundError:
# 文件不存在,可能是第一次运行程序
pass
def load_users_from_file(self):
try:
with open("users.json", "r") as file:
users_data = json.load(file)
for user_data in users_data:
user = User(user_data["username"], user_data["password"])
user.borrowed_books = [Book(book_data["title"], book_data["author"]) for book_data in user_data["borrowed_books"]]
self.users.append(user)
except FileNotFoundError:
# 文件不存在,可能是第一次运行程序
pass
def save_books_to_file(self):
with open("books.json", "w") as file:
books_data = []
for book in self.books:
book_data = {
"title": book.title,
"author": book.author,
"is_checked_out": book.is_checked_out,
}
books_data.append(book_data)
json.dump(books_data, file, indent=2)
def save_users_to_file(self):
with open("users.json", "w") as file:
users_data = []
for user in self.users:
user_data = {
"username": user.username,
"password": user.password,
"borrowed_books": [{"title": book.title, "author": book.author} for book in user.borrowed_books],
}
users_data.append(user_data)
json.dump(users_data, file, indent=2)
def save_data_to_files(self):
self.save_books_to_file()
self.save_users_to_file()
def find_user(self, username, password):
for user in self.users:
if user.username == username and user.password == password:
self.current_user = user
return user
return None
def is_username_taken(self, username):
for user in self.users:
if user.username == username:
return True
return False
# 创建根窗口并运行程序
root = tk.Tk()
app = LibraryApp(root)
root.mainloop()
books.json 和users.json模板文件
users.json模板文件:
[
{
"username": "yli",
"password": "123",
"borrowed_books": [
{
"title": "To Kill a Mockingbird",
"author": "Harper Lee"
}
]
},
{
"username": "pipi",
"password": "456",
"borrowed_books": []
}
]
books模板文件:
[
{
"title": "The Great Gatsby",
"author": "F. Scott Fitzgerald",
"is_checked_out": false
},
{
"title": "To Kill a Mockingbird",
"author": "Harper Lee",
"is_checked_out": true
},
{
"title": "1984",
"author": "George Orwell",
"is_checked_out": false
},
{
"title": "2024",
"author": "Michael Li",
"is_checked_out": false
},
{
"title": "back to 1988",
"author": "X-Man",
"is_checked_out": false
}
]