Skip to main content

tkinter

图书馆系统

描述

创建一个图书馆系统,要求如下:

  1. 有两个类:用户类和图书类
  2. 用户类有属性:姓名、年龄、性别、借书数量、借书列表
  3. 图书类有属性:书名、作者、出版社、价格、状态(是否被借出)
  4. 用户类有方法:借书、还书
  5. 图书类有方法:借出、归还
  6. 用户类和图书类的方法中,需要对用户的借书数量和图书的状态进行判断
  7. 用户类和图书类的方法中,需要对用户的借书列表和图书的状态进行修改
  8. 用户类和图书类的方法中,需要打印出用户的借书列表和图书的状态
  9. 使用图形化界面工具,如tkinter 安装命令 pip install tkinter-page

题解



from tkinter import *

"""
提前安装好模块:pip install tkinter-page
需要掌握的知识:Python基础、Mysql命令、os模块、tkinter模块
"""
from tkinter import *
import sqlite3
import os


class db:
def addmysql(name, author, comment, state): # 添加数据
Desktoppath = "./StrayLibrary/book.db"
db = sqlite3.connect(Desktoppath) # 使用cursor()方法获取操作游标
cursor = db.cursor() # SQL 插入语句
sql = "INSERT INTO EMPLOYEE(name,author,comment,state)VALUES ('{}','{}','{}','{}')".format(
name, author, comment, state
)
try: # 执行sql语句
cursor.execute(sql) # 提交到数据库执行
db.commit()
except: # Rollback in case there is any error
db.rollback()
db.close() # 关闭数据库连接

def changemysql(state, name): # 更改数据状态
Desktoppath = "./StrayLibrary/book.db"
db = sqlite3.connect(Desktoppath)
cursor = db.cursor() # 使用cursor()方法获取操作游标
sql = "UPDATE EMPLOYEE SET state = '%s' where name = '%s' " % (state, name)
try:
cursor.execute(sql)
db.commit()
except:
pass
db.close()

def checkmysql(): # 检索数据库
Desktoppath = "./StrayLibrary/book.db"
db = sqlite3.connect(Desktoppath)
cursor = db.cursor() # 使用cursor()方法获取操作游标
sql = "SELECT * FROM EMPLOYEE" # SQL 查询语句
try:
cursor.execute(sql) # 获取所有记录列表
results = cursor.fetchall()
return results
except:
pass
db.close()

def bulildmysql():
try:
os.makedirs("./StrayLibrary") # 创建一个文件夹
Desktoppath = "./StrayLibrary/book.db" # 文件夹下创建一个数据库
file = open(Desktoppath, "w")
file.close()

db = sqlite3.connect(Desktoppath)
cursor = db.cursor() # 使用cursor()方法获取操作游标
cursor.execute(
"DROP TABLE IF EXISTS EMPLOYEE"
) # 如果数据表已经存在使用 execute() 方法删除表。
sql = """CREATE TABLE EMPLOYEE (name TEXT(255),author TEXT(255),comment TEXT(255),state TEXT(255))"""
cursor.execute(sql) # 创建数据表SQL语句
db.close()
db.addmysql(
"惶然录", "费尔南多·佩索阿", "一个迷失方向且濒于崩溃的灵魂的自我启示、一首对默默无闻、失败、智慧、困难和沉默的赞美诗。", "未借出"
)
db.addmysql(
"以箭为翅", "简媜", "调和空灵文风与禅宗境界,刻画人间之缘起缘灭。像一条柔韧的绳子,情这个字,不知勒痛多少人的心肉。", "未借出"
)
db.addmysql(
"心是孤独的猎手", "卡森·麦卡勒斯", "我们渴望倾诉,却从未倾听。女孩、黑人、哑巴、醉鬼、鳏夫的孤独形态各异,却从未退场。", "已借出"
)
except:
pass


class Book:
def __init__(self, name, author, comment, state):
self.name = name
self.author = author
self.comment = comment
self.state = state

def __str__(self):
return "\n名称:《%s》 \n作者:%s \n推荐语:%s\n状态:%s \n---------" % (
self.name,
self.author,
self.comment,
self.state,
)


class StrayLibrary:
books = []

def __init__(self, init_window_name):
self.init_window_name = init_window_name
results = db.checkmysql()
for row in results:
name = row[0]
author = row[1]
comment = row[2]
state = row[3]
book1 = Book(name, author, comment, state)
self.books.append(book1)

def set_init_window(self): # 设置窗口
self.init_window_name.title("流浪图书馆(StrayLibrary)") # 窗口名
self.init_window_name.geometry("450x260+10+10")
self.result_data_Text = Text(
self.init_window_name, width=35, height=15
) # 处理结果展示
self.result_data_Text.grid(row=1, column=12, rowspan=7, columnspan=7)

self.mianbutton1 = Button(
self.init_window_name,
text="查询(check)",
bg="DodgerBlue",
width=20,
command=self.show_all_book,
) # 调用内部方法 加()为直接调用
self.mianbutton2 = Button(
self.init_window_name,
text="添加(add)",
bg="DodgerBlue",
width=20,
command=self.add_book,
) # 调用内部方法 加()为直接调用
self.mianbutton3 = Button(
self.init_window_name,
text="借阅(lend)",
bg="DodgerBlue",
width=20,
command=self.lend_book,
) # 调用内部方法 加()为直接调用
self.mianbutton4 = Button(
self.init_window_name,
text="归还(return)",
bg="DodgerBlue",
width=20,
command=self.return_book,
) # 调用内部方法 加()为直接调用
self.mianbutton1.grid(row=1, column=11)
self.mianbutton2.grid(row=3, column=11)
self.mianbutton3.grid(row=5, column=11)
self.mianbutton4.grid(row=7, column=11)

# 功能函数
def show_all_book(self):
self.result_data_Text.delete(0.0, END)
for book in self.books:
self.result_data_Text.insert(1.0, book)

def add_book(self):
top = Tk()
top.title("添加(add)")
top.geometry("300x120+450+10")
self.L1 = Label(top, text="请输入书籍名称:")
self.E1 = Entry(top, bd=5)
self.L2 = Label(top, text="请输入作者名称:")
self.E2 = Entry(top, bd=5)
self.L3 = Label(top, text="请输入书籍推荐语:")
self.E3 = Entry(top, bd=5)
self.L1.place(x=0, y=0)
self.L2.place(x=0, y=30)
self.L3.place(x=0, y=60)
self.E1.place(x=120, y=0)
self.E2.place(x=120, y=30)
self.E3.place(x=120, y=60)
self.B = Button(top, text="输入完毕请点击确认,无需继续输入请关闭窗口", command=self.add_booking)
self.B.pack(side=BOTTOM)

def add_booking(self):
new_name = self.E1.get()
new_author = self.E2.get()
new_comment = self.E3.get()
self.result_data_Text.delete(0.0, END)
new_book = Book(new_name, new_author, new_comment, "未借出")
self.books.append(new_book)
db.addmysql(new_name, new_author, new_comment, "未借出") # 写入数据库
self.result_data_Text.insert(1.0, new_name + "录入成功!\n")

def check_book(self, name):
for book in self.books:
if book.name == name:
return book
else:
return None

def lend_book(self):
toplend = Tk()
toplend.title("借阅(lend)")
toplend.geometry("330x50+450+30")
self.lendE1 = Entry(toplend, bd=5)
self.lendE1.pack(side=RIGHT)
self.lendB1 = Button(toplend, text="输入书名,输入完毕请点击", command=self.lend_booking)
self.lendB1.pack(side=LEFT)

def lend_booking(self):
name = self.lendE1.get()
res = self.check_book(name)
self.result_data_Text.delete(0.0, END)
if res != None:
if res.state == "已借出":
self.result_data_Text.insert(1.0, "你来晚了一步,这本书已经被借走了噢")
else:
res.state = "已借出"
db.changemysql("已借出", res.name)
self.result_data_Text.insert(1.0, "借阅成功,借了不看会变胖噢~")
else:
self.result_data_Text.insert(1.0, "这本书暂时没有收录在系统里呢")

def return_book(self):
topreturn = Tk()
topreturn.title("归还(return)")
topreturn.geometry("330x50+450+30")
self.returnE1 = Entry(topreturn, bd=5)
self.returnE1.pack(side=RIGHT)
self.returnB1 = Button(
topreturn, text="输入书名,完毕请点击", command=self.return_booking
)
self.returnB1.pack(side=LEFT)

def return_booking(self):
name = self.returnE1.get()
res = self.check_book(name) # 调用check_book方法,将返回值赋值给变量res
self.result_data_Text.delete(0.0, END)
if res == None: # 如果返回的是空值,即这本书的书名不在系统里
self.result_data_Text.insert(1.0, "没有这本书噢,你恐怕输错了书名~")
else: # 如果返回的是实例对象
if res.state == "未借出": # 如果实例属性state等于0,即这本书的借阅状态为'未借出'
self.result_data_Text.insert(1.0, "这本书没有被借走,在等待有缘人的垂青呢!")
else: # 如果实例属性state等于1,即状态为'已借出'
self.result_data_Text.insert(1.0, "归还成功!")
res.state = "未借出" # 归还后书籍借阅状态为0,重置为'未借出'
db.changemysql("未借出", res.name)


def gui_start():
db.bulildmysql()
init_window = Tk() # 实例化出一个父窗口
ZMJ_PORTAL = StrayLibrary(init_window) # 设置根窗口默认属性
ZMJ_PORTAL.set_init_window()
init_window.mainloop() # 父窗口进入事件循环,可以理解为保持窗口运行,否则界面不展示


gui_start()