为python初学者练习,现有一个开发练习,自由设计共享图书管理系统,包括用户和管理员功能设计。本篇为方便初学者界面设计,使用python自带库tkinter完成界面设计。
一、引言
1.1编写目的:
本报告的编写目的是规范软件的编写,作为软件程序编写的依据,旨在提高开发过程中的能见度。便于程序员与用户之间的沟通、交流。本报告也是进行项目策划、概要设计和详细设计的基础,是维护人员内部维护验收和测试的依据。
1.2背景和范围
项目名称:共享图书管理系统
项目开发者:
本项目针对用户登录系统进行图书共享、管理员登录系统进行书目管理和用户管理。
二、项目描述
2.1开发目标
所有用户均可在系统进行用户注册,用户登录后可以达到各取所需,选择图书和共享图书。管理员可以查看图书信息也可以对违规读者黑名单处理。
2.2应用范围:
理论上实现供所有用户的使用
2.3 子集说明
本系统分为两个大模块,一是用户模块:注册使用、共享图书、查看借阅和已共享书籍、账号信息、修改密码等。二是管理员模块分为普通管理员模块和超级管理员模块,普通管理员可以删除用户、查看书籍情况、查看某个用户的借阅情况、将用户的密码重置等,超级管理员除拥有管理员的权限外,还可以注册管理员,删除管理员,修改管理员的密码,而普通管理员是没有这些权限
2.4 软件功能描述
用户可以把想要共享的图书信息发布到共享图书系统上,系统将书籍信息录入,所有使用者均可借阅。对于使用者而言,系统提供平台,让需求者可以检索到自己想要的书目。系统管理员可以查看和删除用户信息及查看书籍状态和用户借阅情况。增设超级管理员,可以管理所有管理员及用户超级管理员的账号密码有一初始账号密码,超级管理员可以通过设定账号密码登录也可以更改密码。
三、软件属性
3.1可用性
由于自身能力有限,本项目功能仅限所列的功能
3.2安全性
数据会被保存在数据库中,除管理员外,数据不会轻易被修改。数据若遭到破坏可重新录入数据信息。
四、功能结构图
一、主页面模块
输入分为两个部分--用户输入及管理员输入。程序运行弹出的主页面设计为使用者的身份选择以及本项目的相关说明页面。此为整个程序运行的首要页面,再通过button按钮中的command调用管理员页面及用户登录界面。
二、用户模块
理论上本项目面向对象为所有的使用者,故用户的输入模块面向大众。用户登录部分创建一个类与主页面对接,在用户登录界面所呈现的是账号密码的输入用于注册和登录以及程序的退出。
2.1 用户注册
在登录页面输入账号及密码点击注册按钮即可完成注册,注册按钮command回调账号密码信息写入文本函数。
2.2 用户登录
完成账号密码注册的用户即可进行登录操作,在用户点击登录按钮后系统内部判断输入内容是否为空白,账号密码是否正确。若输入为空则弹出提示框提示输入不能为空,若账号密码不正确则提示,登陆失败。若账号密码正确则进入用户查看书籍信息、共享图书等等功能的页面。该页面为一新类与登录按钮
2.3 用户功能界面
在该页面内读者可以选择自己想要进行的选项,初步设定的功能有查询图书、借阅图书、共享图书、查看账户信息以及退出。
2.3.1 查询图书
设置回调函数,在点击查询图书后弹出新窗口,在新窗口中的Entry控件中输入要查找的书名,在点击查找按钮后调用回调函数判断输入内容--是否为空、是否输入正确,该判断过程与登录界面过程基本类似。
2.3.2借阅图书
用户在查询图书后可以选择是否借阅该本图书。
2.3.3 共享图书
用户点击共享图书按钮后,弹出窗口,使用label指引用户依次输入书名、作者、出版社、价格,Entry提供输入框,再使用get方法读取用户输入,将信息以列表的形式存入文件,以便对书籍信息的管理。在用户点击确定后command方法调用回调函数判断用户的输入是否为空,该方法与前文所述一致。
2.3.4 查看账户信息
用户可以通过点击按钮查看自己的账户共享了什么书,借阅了什么书,以及自己账户信息。程序从文件或表格中读取信息。
三、管理员模块(说明:普通管理基于超级管理员的管理,普通管理员账户仅能通过超级管理员来注册,超级管理员账号密码内设,普通管理员登陆页面仅有登录权限)
3.1 普通管理员
3.1.1管理员登录
管理员登录界面和用户登录界面基本一致,故可以子类继承父类(用户的登录模块)。但在登录成功后command方法中回调函数稍有区别,即管理员有比用户更多的权限。
3.1.2 功能界面
功能界面使用类的继承,沿用用户的功能界面,由于稍有区别,故可在子类中做修改,增加查看用户信息的功能--在管理员点击bottom按钮后跳出所有的用户信息,包括用户名、账号和密码以及用户借阅图书的情况和共享图书的情况。管理员还可在用户信息界面对用户的账户做删除处理,在输入框内输入读者号后,点击删除按钮,调用回调函数,从excel表格中找到该读者,将读者号更改使读者无法正常登录即可。这其中需要对继承的类需要进行必要的修改。
3.2 超级管理员
3.2.1 超级管理员账户
超级管理员账户由设计者提前设定,默认一个初始密码,可以进行修改密码操作。超级管理员的权限最高,普通管理员由超级管理员注册。
3.2.2 超级管理员功能界面
超级管理员拥有管理员的一切权限,且普通管理员的新增和删除由超级管理员操作,超级管理员还可以修改自己的密码和普通管理员的密码,普通管理员和超级管理员界面相同,但在普通管理员点击未授予的权限时弹出没有权限的窗口。故超级管理员可以直接继承普通管理员的类并在基础上做方法的改写。
#主窗口界面
top = tk.Tk()
initialpage(top)
tk.Label(top, text="欢迎进入共享图书系统!", bg="red", font="20 ").place(x=190,y=50)
tk.Button(top, text="读者登录", width=15,height=2, command=usersigninpage).place(x=230,y=100)
tk.Button(top, text="管理员登录", width=15,height=2,command=manager_page ).place(x=230,y=150)
tk.Button(top, text="读者注册", width=15,height=2,command=registerpage).place(x=230,y=200)
tk.Button(top, text="退出", width=15,height=2,command=top.quit).place(x=230,y=250)
top.mainloop()
展现窗口如下:
初始化界面调用:
#初始化界面函数
class initialpage:
def __init__(self,window):
window.title("共享图书管理系统")
width = 600 #设置界面宽度
height = 400 #设置界面长度
screenwidth = window.winfo_screenwidth() #读取屏幕宽度
screenheight = window.winfo_screenheight() #读取屏幕长度
size_geo = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
window.geometry(size_geo) #窗口位置
window.maxsize(600, 600) #最大大小
window.minsize(50, 50) #最小大小
class usersigninpage():
# 登录窗口的创建
def __init__(self):
win = tk.Tk() #创建窗口
initialpage(win)#调用创建窗口函数
# 登录信息
sign = tk.Label(win, text="欢迎进入共享图书系统!", bg="red", font="20 ") #设置提示
sign.place(x=190, y=50)
namelab = tk.Label(win, text="读者号:")
namelab.place(x=200, y=120)
passwordlab = tk.Label(win, text="密码:")
passwordlab.place(x=200, y=150)
# 创建输入框控件
e1 = tk.Entry(win, width=15)
# 以 * 的形式显示密码
e2 = tk.Entry(win, width=15, show='*')
e1.place(x=270, y=120)
e2.place(x=270, y=150)
wb = load_workbook('C:\\Users\\albert\\Desktop\\user_data.xlsx')
sheet1 = wb[wb.sheetnames[0]]
# 验证登录账户密码是否正确回调函数
def login():
account = eval(e1.get())
password = e2.get()
if password == sheet1.cell(account+1,3).value:
userpage()
else:
messagebox.showinfo(title='温馨提示', message='登陆失败!')
win.destroy()
# 显示按钮位置
sign_in = tk.Button(win, text="登录", width=10, command=login) # 登录设置
sign_in.place(x=250, y=250)
#用户功能界面
def userpage():
book = tk.Tk() #新建窗口
initialpage(book)#调用创建窗口函数
sign = tk.Label(book, text="欢迎进入共享图书系统!", bg="red", font="20 ") # 设置提示
sign.place(x=190, y=50)
# 目录栏创建
mainmenu = tk.Menu(book) # 主目录创建
filemenu1 = tk.Menu(mainmenu, tearoff=False) # 子目录创建
filemenu1.add_command(label="共享信息",command=share_information )#设置选项
filemenu1.add_command(label="借阅信息", command=borrow_information)
filemenu1.add_command(label="账号信息",command=account_information )
mainmenu.add_cascade(label="查看", menu=filemenu1)
mainmenu.add_command(label='查找', command=search)
filemenu2 = tk.Menu(mainmenu, tearoff=False) # 子目录创建
filemenu2.add_command(label="共享图书", command=share)
mainmenu.add_cascade(label="添加", menu=filemenu2)
mainmenu.add_command(label="还书", command=back)
mainmenu.add_command(label="退出", command=book.destroy)
book.config(menu=mainmenu)
book.mainloop()
def share_information():
newwin = tk.Tk()
initialpage(newwin)#调用创建窗口函数
sign = tk.Label(newwin, text="您已共享的图书有:",bg='yellow',font="15 ")
sign.place(x=190, y=20)
wb = load_workbook('C:\\Users\\albert\\Desktop\\user_data.xlsx')
sheet = wb[wb.sheetnames[0]]
a = eval(e1.get())
inf = str(sheet.cell(a + 1, 5).value).split(' ') #以空格为间隔将字符串读取为列表
t = len(inf)
c = ''
for h in range(1, t): #将列表读取为字符串
s = inf[h] + ' '
c = c + s
tk.Label(newwin,text=c).place(x=30,y=50)
newwin.mainloop()
def borrow_information():
newwin = tk.Tk()
initialpage(newwin) # 调用创建窗口函数
sign = tk.Label(newwin, text="您已借阅的图书有:", bg='yellow', font="15 ")
sign.place(x=190, y=20)
wb = load_workbook('C:\\Users\\albert\\Desktop\\user_data.xlsx')
sheet = wb[wb.sheetnames[0]]
a = eval(e1.get())
inf = str(sheet.cell(a + 1, 4).value).split(' ') # 以空格为间隔将字符串读取为列表
t = len(inf)
c = ''
for h in range(1, t): # 将列表读取为字符串
s = inf[h] + ' '
c = c + s
tk.Label(newwin, text=c).place(x=30, y=50)
newwin.mainloop()
def account_information():
newwin = tk.Tk()
initialpage(newwin)#调用创建窗口函数
sign = tk.Label(newwin, text="账号信息", bg='yellow', font="15 ")
sign.place(x=150, y=20)
tk.Label(newwin, text="姓名:").place(x=30,y=50)
tk.Label(newwin, text="读者号:").place(x=30,y=80)
tk.Label(newwin, text="密码:").place(x=30,y=110)
wb = load_workbook('C:\\Users\\albert\\Desktop\\user_data.xlsx')
w = wb.active
sheet = wb[wb.sheetnames[0]]
a = eval(e1.get())
tk.Label(newwin, text=sheet.cell(a + 1, 2).value).place(x=80, y=50)
tk.Label(newwin, text=sheet.cell(a + 1, 1).value).place(x=80, y=80)
tk.Label(newwin, text=sheet.cell(a + 1, 3).value).place(x=80, y=110)
def change_password():
another_win = tk.Tk()
initialpage(another_win)
tk.Label(another_win, text="旧密码:").place(x=30, y=50)
tk.Label(another_win, text="新密码:").place(x=30, y=80)
tk.Label(another_win, text="确认密码:").place(x=30, y=110)
p1 = tk.Entry(another_win, width=15, show='*')
p1.place(x=100,y=50)
p2 = tk.Entry(another_win, width=15, show='*')
p2.place(x=100, y=80)
p3 = tk.Entry(another_win, width=15, show='*')
p3.place(x=100, y=110)
def test():
if p1.get() == '' or p2.get() == '' or p3.get() == '':
messagebox.showinfo(title='Error', message='输入不能为空')
elif p1.get() != sheet.cell(a + 1, 3).value:
messagebox.showinfo(title='Error', message='原始密码错误')
elif p2.get() == p1.get():
messagebox.showinfo(title='Error', message='新密码与原密码一致')
elif p2.get() != p3.get():
messagebox.showinfo(title='Error', message='两次输入不一致')
elif p2.get() == p3.get():
w.cell(row=a + 1, column=3, value=p3.get())
messagebox.showinfo(title='温馨提示', message='更改成功!')
wb.save('C:\\Users\\albert\\Desktop\\user_data.xlsx')
wb.close()
another_win.destroy()
tk.Button(another_win, text="确定", width=10, command=test).place(x=80,y=150)
tk.Button(newwin, text="修改密码", width=10, command=change_password).place(x=80, y=150)
tk.Button(newwin, text="退出", width=10, command=newwin.destroy).place(x=80, y=200)
def back():
newwin = tk.Tk()
initialpage(newwin)
x1 = tk.Label(newwin, text="书名:")
x1.place(x=50, y=10)
s1 = tk.Entry(newwin, width=15)
s1.place(x=80, y=10)
def back1():
wa = load_workbook('C:\\Users\\albert\\Desktop\\bookinformation.xlsx')
sheet1 = wa[wa.sheetnames[0]]
ws = wa.active
num = 1
while 1:
cell = ws.cell(row=num, column=1).value
if cell:
num = num + 1
else:
line = num
break
wb = load_workbook('C:\\Users\\albert\\Desktop\\user_data.xlsx')
w = wb.active
sheet = wb[wb.sheetnames[0]]
a = eval(e1.get())
inf = str(sheet.cell(a + 1, 4).value).split(' ')
if s1.get() in inf:
for i in range(2, line + 1):
if s1.get() == str(sheet1.cell(i, 1).value):
break
if s1.get() == str(sheet1.cell(i, 1).value):
ws.cell(row=i,column=5,value='在馆')
wa.save('C:\\Users\\albert\\Desktop\\bookinformation.xlsx')
wa.close()
inf.remove(s1.get())
t = len(inf)
c = ''
for h in range(1,t):
s = inf[h] + ' '
c = c + s
w.cell(row=a + 1, column=4, value=c)
wb.save('C:\\Users\\albert\\Desktop\\user_data.xlsx')
wb.close()
messagebox.showinfo(title='温馨提示', message='还书成功!')
newwin.destroy()
else:
messagebox.showinfo(title='温馨提示', message='无法还书!请检查')
newwin.destroy()
s2 = tk.Button(newwin, text=