一、实验目的
1.实现管理系统的可视化界面设计
2.实现管理系统连接数据库操作
3.实现管理系统的基本功能(增删改查)
4.实现注册、权限管理、导出成绩等个性化操作
二、实验内容
1.使用Tkinter设计按钮、界面、触发响应等布局和操作
2.使用Pycharm连接数据库、编写数据库语言
3.编写注册、管理员等操作
4.分配各种人员的权限
5.美化界面和LOGO
三、实验过程
3.1 界面功能设计
我们采用分布式界面设计,以主界面为载体,通过设计触发按钮,将其余界面定义为函数,等待触发按钮的调用,最终实现界面的嵌套出现。图1是我们的登陆界面。
主界面的代码展示如下:
学生注册界面我们设置为监听触发,打开填写,使用get()函数监听是否有输入情况。如果学号输入小于12位,提示“学号为12位数字,请重新输入!”,如果学号输入重复,提示“学号重复,注册失败,请修改学号”。
如果注册成功,则将注册信息输入student_info表格中。注册窗口如图2所示。
注册成功后,我们输入账号,密码进入学生界面(如图3所示),此界面设置查看成绩和修改登陆密码两个权限,分别对应查看student_achievement表和修改student_info两个表格(如图4、5)。
导出excel表格主要是运用Python中的xlwt库,创建全局变量numbers,通过调用查找student_achievement库的操作获取当前学生的成绩,双for循环将数据输入到新建的sheet1中,close()保存。最后命名为student_achievements.xls,并输出“导出成功!”。
注意:定义excel的输出形式的时候一定要记得填写文件的格式为utf-8,否则会出现类体调用重复的错误。
在每个框架的代码中都加入了限制条件,限制操作人员对界面框的自由拖动,实现整体的稳定。
在老师登陆界面我们设计了和学生登陆界面类似的结构,分别是查看学生成绩和修改学生成绩。如图6所示。
查看学生成绩弹窗中主要是查看所有学生的成绩和导出某一科的成绩,为了方便老师操作,我们设置了按照升序导出和按照降序导出。这里主要的操作是对student_achievement表进行查看。
选择科目这个下拉框的操作是通过调用数据库接口函数achievement_lie_name() 反馈表格中有多少种学科。通过动态游标掌握选择的科目,回传给后续的函数。最终导出成绩如图7所示。
导出的操作和之前类似,通过遍历列表,存入excel表格中调用。
修改学生成绩涉及到的变量比较多,所以人机交互框也最多如图8所示,这里我们需要用户选择学生的学号,学生的科目和修改的分数三个变量才能进行数据库操作。如果没有科目,则会选择添加科目,对student_achievement表添加一行,所有值均为NONE。
这里涉及到数据库列的增加和对特定位置数值的修改,为了窗口美观我们设置了操作界面居中,窗口固定等操作。
同时注意,这里的监听响应类型不同,学号、科目、候选栏都是字符型监听输入,而成绩是整型监听输入,而且要限制输入的范围是0~100。
管理员登陆界面主要分为四个部分查看学生成绩单、修改学生成绩、添加教师账号、修改教师账号。如图9所示。这里涉及到的功能主要是对前面老师和学生的功能的汇总。
其中新添加了对教师账号的增加和删除,这里考虑到教师不会随意变动账号,所以我们没有设计对教师账号的修改,并赋予管理员操作教师teacher_info表格的能力。这里的添加教师账号和登陆界面注册学生账号类似。
3.2 角色权限设计
这里主要分为三个角色:管理员、学生和老师,总体的功能主要分为学生表的查看,单个学生成绩查看,学生注册,学生成绩修改,教师注册,学生成绩修改,涉及到数据库的增删改查。
管理员:学生表查看,学生成绩修改,教师表增加、删除
学生:学生成绩表查看,修改注册表
老师:查看学生成绩表,修改学生成绩表
3.3 SQLlite数据库接口设计
在Navicat Primium中创建、连接student数据库,后编写数据库中所需要用到的学生成绩、学生信息、老师信息,结果如下图所示。
接着实现数据库与pycharm的连接,连接成功如下图所示。
打开连接数据库,在pycharm中实现对数据库对学生成绩表的创建,其后实现查询列名、查询学生成绩、添加新科目、同步信息、删除信息等操作。
Achievement_opendb函数实现连接学生成绩数据库,创建connect连接对象(student.db)、创建cursor游标对象、执行sql语句、关闭游标、
如上图所,在achievement_opendb函数中con实现连接student.db数据库,游标对象为cur(数据库学生成绩表中的学号和姓名);而在achievement_lie_name函数中,游标对象cur(student.db)执行查询学生成绩表的操作,返回值为游标中所展示的所有列名,随后关闭游标。其它相关功能与其类似。
四、实验结果展示
4.1注册展示
学生信息按照要求填写姓名、年龄、学号、密码。
后台数据库出现注册信息,注册功能正常。
4.2学生成绩查询展示
4.2.1个人成绩查询
登陆个人账号,点击查询:
和后台数据库相同,查询正确。
4.2.2 教师/管理员查询学生总成绩
教师/管理员登陆系统,点击查询成绩:
和后台数据库显示的学生成绩相同,查询正确。
4.3学生成绩修改展示
管理员/教师修改学生成绩,将学号为202210104119的学生的软件工程的成绩修改为100分:
和后台数据显示的结果相同,修改成功。
4.4数据库导出为excel展示
导出202210104119号学生的全部成绩到当前文件夹,保存为xls格式:
和后台数据库的成绩相同,说明导出正确。
4.5打包封装展示
使用pyinstaller库对代码进行打包和封装,并且添加logo:
五、代码展示
管理员界面
# -*- coding:utf-8 -*-
from tkinter.messagebox import *
from tkinter import *
from student_info_sql import *
from teacher_info_sql import *
from student_achievement_sql import *
from tkinter import ttk
import xlwt
class AdminPage(object):
def __init__(self, master=None):
self.root = master #定义内部变量root
self.root.geometry('%dx%d' % (650, 350)) #设置窗口大小
self.root.resizable(0,0) #防止用户调整尺寸
self.createPage()
def createPage(self):
self.admin_menuPage = admin_MenuFrame(self.root) # 创建不同Frame
# self.menuPage.pack() #默认显示界面
bm = PhotoImage(file=r'JUST2.gif')
self.lab3 = Label(self.root, image=bm)
self.lab3.bm = bm
self.lab3.pack()
class admin_MenuFrame(Frame): # 继承Frame类
def __init__(self, master=None):
Frame.__init__(self, master)
self.root = master #定义内部变量root
self.createPage()
def createPage(self):
Button(self.root, text='查看学生成绩单', command=self.print_student_ach,width=15,height=5).place(x=200, y=95)
Button(self.root, text='修改学生成绩',command=self.change_ach,width=15,height=5).place(x=350, y=95)
Button(self.root, text='添加教师账号',command=self.teacher_sign_up,width=15,height=5).place(x=200, y=195)
Button(self.root, text='删除教师账号',command=self.dele_teacher_number,width=15,height=5).place(x=350, y=195)
def dao_xls(self):
a=user_slectTable()
b=user_lie_name()
a.insert(0,tuple(b))
def w_excel(res):
book = xlwt.Workbook(encoding='utf-8') #新建一个excel
sheet = book.add_sheet('sheet1') #新建一个sheet页
for row in range(0,len(res)):
for col in range(0,len(res[row])):
sheet.write(row,col,res[row][col])
row+=1
col+=1
book.save('student_info.xls')
print("导出成功!")
w_excel(a)
showinfo(title='确认', message='导出成功!')
def dele_teacher_number(self):
def sure_dele():
try:
Teacher_number=self.teacher_number.get()
teacher_deldb(Teacher_number)
showinfo(title='确认', message='删除成功!')
self.dele_menu.destroy()
except:
showinfo(title='错误', message='未知错误,请重新删除!')
self.dele_menu.destroy()
self.dele_menu = Toplevel(self.root)
self.dele_menu.title('删除教师账号')
winWidth = 200
winHeight = 200
screenWidth = self.dele_menu.winfo_screenwidth()
screenHeight = self.dele_menu.winfo_screenheight()
x = int((screenWidth - winWidth) / 2)
y = int((screenHeight - winHeight) / 2)
# 设置窗口初始位置在屏幕居中
self.dele_menu.geometry("%sx%s+%s+%s" % (winWidth, winHeight, x, y))
# 设置窗口图标
# root.iconbitmap("./image/icon.ico")
# 设置窗口宽高固定
self.dele_menu.resizable(0, 0)
self.teacher_number=StringVar()
Label(self.dele_menu, text='教师号: ').place(x=10, y=30)
Entry(self.dele_menu, textvariable=self.teacher_number).place(x=50, y=30)
Button(self.dele_menu, text='确认删除',command=sure_dele).place(x=80, y=80)
def change_ach(self):
def add_new_subject():
def sure_add():
try:
Subject_name=self.subject_name.get()
achievement_insertData(Subject_name)
showinfo(title='确认', message='添加成功!')
self.dele_menu.destroy()
except:
showinfo(title='错误', message='未知错误,请重新修改!')
self.dele_menu.destroy()
self.change_menu.destroy()
self.dele_menu = Toplevel(self.root)
self.dele_menu.title('修改学生成绩')
winWidth = 200
winHeight = 200
screenWidth = self.dele_menu.winfo_screenwidth()
screenHeight = self.dele_menu.winfo_screenheight()
x = int((screenWidth - winWidth) / 2)
y = int((screenHeight - winHeight) / 2)
# 设置窗口初始位置在屏幕居中
self.dele_menu.geometry("%sx%s+%s+%s" % (winWidth, winHeight, x, y))
# 设置窗口图标
# root.iconbitmap("./image/icon.ico")
# 设置窗口宽高固定
self.dele_menu.resizable(0, 0)
self.subject_name=StringVar()
Label(self.dele_menu, text='科目名: ').place(x=10, y=30)
Entry(self.dele_menu, textvariable=self.subject_name).place(x=50, y=30)
Button(self.dele_menu, text='确认添加',command=sure_add).place(x=80, y=80)
def sure_change():
try:
Student_number=self.student_number.get()
Student_ach=self.student_ach.get()
Subject_name=self.comvalue.get()
if Student_ach >100 or Student_ach < 0:
showinfo(title='错误', message='成绩数值错误,请重新修改!')
else:
achievement_alter(Student_number,Subject_name,Student_ach)
showinfo(title='确认', message='修改成功!')
self.change_menu.destroy()
except:
showinfo(title='错误', message='未知错误,请重新修改!')
self.change_menu.destroy()
self.change_menu = Toplevel(self.root)
self.change_menu.title('修改学生成绩')
winWidth = 550
winHeight = 300
screenWidth = self.change_menu.winfo_screenwidth()
screenHeight = self.change_menu.winfo_screenheight()
x = int((screenWidth - winWidth) / 2)
y = int((screenHeight - winHeight) / 2)
# 设置窗口初始位置在屏幕居中
self.change_menu.geometry("%sx%s+%s+%s" % (winWidth, winHeight, x, y))
# 设置窗口图标
# root.iconbitmap("./image/icon.ico")
# 设置窗口宽高固定
self.change_menu.resizable(0, 0)
def go(*args):
#处理事件,*args表示可变参数
print(comboxlist.get())
return comboxlist.get()#打印选中的值
self.comvalue=StringVar()#窗体自带的文本,新建一个值
comboxlist=ttk.Combobox(self.change_menu,textvariable=self.comvalue) #初始化
achievement_lie_name()#获取科目列表
b=achievement_lie_name()
# print(b)
a=[]
j=0
for i in b:
if j>=2:
a.append(i)
j+=1
a=tuple(a)
# print(a)
comboxlist["values"]=a
comboxlist.current(0) #选择第一个
comboxlist.bind("<<ComboboxSelected>>",go) #绑定事件,(下拉列表框被选中时,绑定go()函数)
Label(self.change_menu, text="请选择科目").place(x=140, y=50)
comboxlist.place(x=230, y=50)
Label(self.change_menu, text="如果没有科目").place(x=140, y=98)
Button(self.change_menu, text='请添加科目',command=add_new_subject,width=22).place(x=230, y=95)
self.student_number = StringVar()
self.student_ach = IntVar()
Label(self.change_menu, text='学号: ').place(x=180, y=150)
Entry(self.change_menu, textvariable=self.student_number).place(x=220, y=150)
Label(self.change_menu, text='成绩(0~100): ').place(x=135, y=200)
Entry(self.change_menu, textvariable=self.student_ach).place(x=220, y=200)
Button(self.change_menu, text='确认修改',command=sure_change).place(x=250, y=250)
def teacher_sign_up(self):
def insert_sql():
try:
age = self.new_age.get()
number = self.new_number.get()
name = self.new_name.get()
pw = self.new_pw.get()
XWC=user_showdb(number)
SHB=teacher_showdb(number)
if XWC == None and SHB == None:
teacher_insertData(number,name,pw,age)
showinfo(title='提示', message='注册成功')
self.window_sign_up.destroy()
else:
showinfo(title='提示',message='教师号重复,注册失败,请修改教师号!')
except:
showinfo(title='错误',message='输入错误,请重新输入!')
self.window_sign_up = Toplevel(self.root)
winWidth = 300
winHeight = 200
self.window_sign_up.title('注册窗口')
screenWidth = self.window_sign_up.winfo_screenwidth()
screenHeight = self.window_sign_up.winfo_screenheight()
x = int((screenWidth - winWidth) / 2)
y = int((screenHeight - winHeight) / 2)
# 设置窗口初始位置在屏幕居中
self.window_sign_up.geometry("%sx%s+%s+%s" % (winWidth, winHeight, x-50, y-50))
# 设置窗口图标
# root.iconbitmap("./image/icon.ico")
# 设置窗口宽高固定
self.window_sign_up.resizable(0, 0)
self.new_name = StringVar()
Label(self.window_sign_up, text='姓名: ').place(x=10, y=10)
entry_new_name = Entry(self.window_sign_up, textvariable=self.new_name)
entry_new_name.place(x=130, y=10)
self.new_age= StringVar()
Label(self.window_sign_up, text='年龄: ').place(x=10, y=50)
entry_usr_age = Entry(self.window_sign_up, textvariable=self.new_age)
entry_usr_age.place(x=130, y=50)
self.new_number = StringVar()
Label(self.window_sign_up, text='教师号: ').place(x=10, y=90)
entry_student_number = Entry(self.window_sign_up, textvariable=self.new_number)
entry_student_number.place(x=130, y=90)
self.new_pw = StringVar()
Label(self.window_sign_up, text='密码: ').place(x=10, y=130)
entry_usr_pw = Entry(self.window_sign_up, textvariable=self.new_pw, show='*')
entry_usr_pw.place(x=130, y=130)
sign_up = Button(self.window_sign_up, text='注册', command=insert_sql)
sign_up.place(x=237, y=160)
def print_student_ach(self):
self.teacher_menu = Toplevel(self.root)
self.teacher_menu.title('学生成绩单')
winWidth = 650
winHeight = 400
screenWidth = self.teacher_menu.winfo_screenwidth()
screenHeight = self.teacher_menu.winfo_screenheight()
x = int((screenWidth - winWidth) / 2)
y = int((screenHeight - winHeight) / 2)
# 设置窗口初始位置在屏幕居中
self.teacher_menu.geometry("%sx%s+%s+%s" % (winWidth, winHeight, x-50, y-50))
# 设置窗口图标
# root.iconbitmap("./image/icon.ico")
# 设置窗口宽高固定
self.teacher_menu.resizable(0, 0)
S=Scrollbar(self.teacher_menu)
T=Text(self.teacher_menu,width=400)
S.pack(side=RIGHT,fill=Y)
T.pack(side=LEFT,fill=Y)
S.config(command=T.yview)
T.config(yscrollcommand=S.set)
# insert的第一个参数为索引;第二个为添加的内容
all_str=achievement_slectTable()
b=achievement_lie_name()
strss=" 学号"+" |"+" 姓名"+" |"
for i,j in enumerate(b):
if i>=2:
strss+=" "+str(j)+" |"
strss+='\n\n'
T.insert(END,strss)
for i in all_str:
strs=""
for j in i:
strs=strs+" "+str(j)+" |"
strs+="\n\n"
T.insert(END,strs)
T.pack()
窗口
# -*- coding:utf-8 -*-
from tkinter.messagebox import *
from tkinter import *
from tkinter import ttk
from student_info_sql import *
from teacher_info_sql import *
from student_achievement_sql import *
from AdminPage import *
import xlwt
global numbers,i
i=0
class LoginPage(object):
def __init__(self, master=None):
self.root = master
winWidth = 550
winHeight = 300
screenWidth = self.root.winfo_screenwidth()
screenHeight = self.root.winfo_screenheight()
x = int((screenWidth - winWidth) / 2)
y = int((screenHeight - winHeight) / 2)
# 设置窗口初始位置在屏幕居中
self.root.geometry("%sx%s+%s+%s" % (winWidth, winHeight, x, y))
# 设置窗口宽高固定
self.root.resizable(0, 0)
self.student_number = StringVar()
self.student_pw = StringVar()
self.createPage()
def createPage(self):
'''
登录页面
1:创建图片组件
2:根目录基础上添加Frame容器
3:Frame容器上添加注册控件
'''
bm=PhotoImage(file=r'JUST2.gif')
self.lab3=Label(self.root,image=bm)
self.lab3.bm=bm
self.lab3.pack()
self.page = Frame(self.root)
self.page.pack()
Label(self.page).grid(row=0, stick=W)
Label(self.page, text = '学号: ').grid(row=1, stick=W, pady=10)
Entry(self.page, textvariable=self.student_number).grid(row=1, column=1, stick=E)
Label(self.page, text = '密码: ').grid(row=2, stick=W, pady=10)
Entry(self.page, textvariable=self.student_pw, show='*').grid(row=2, column=1, stick=E)
Button(self.page, text='管理员登录', command=self.admin_loginCheck).grid(row=3, column=0)
#self.root.bind('<KeyPress-Return>',self.admin_loginCheck1)#绑定键盘上的回车登录
Button(self.page, text='学生注册',command=self.signup).grid(row=3, column=3)
Button(self.page, text='学生/教师登录', command=self.student_loginCheck).grid(row=3,column=1)
#self.root.bind('<KeyPress-Return>',self.user_loginCheck1)#绑定键盘上的回车登录
def admin_loginCheck(self):
global numbers
'''
管理员登录
1:获取管理员账号与密码
2:将获取到的账号与密码与数据库文件配对,配对成功返回值为正确,否则为错误
3:将返回值判断,正确则登录界面清除,登录界面图片清除,进入管理员界面
异常捕获:未填写账号或者密码
'''
try:
Admin_number=self.student_number.get()
#print(User_id)
Admin_pw=self.student_pw.get()
#print(User_pw)
# pd=admin_Select_id_pw(Admin_id,Admin_pw)
# if pd:
if Admin_number=="1" and Admin_pw=="1":
self.page.destroy()
self.lab3.pack_forget()
AdminPage(self.root)
else:
showinfo(title='错误', message='账号或密码错误!')
except:
showinfo(title='错误',message='输入错误,请重新输入!')
def student_loginCheck(self):
global numbers,i
'''
学生登录
1:获取学生学号与密码
2:将获取到的学号与密码与数据库文件配对,配对成功返回值为正确,否则为错误
3:将返回值判断,正确则登录界面清除,登录界面图片清除,进入用户界面,异常捕获:未填写账号或者密码
'''
try:
Student_number=self.student_number.get()
#print(User_id)
Student_pw=self.student_pw.get()
#print(User_pw)
pd_student=user_slect_number_pw(Student_number,Student_pw)
pd_teacher=teacher_slect_number_pw(Student_number,Student_pw)
if pd_student:
numbers=Student_number
self.page.destroy()
self.lab3.pack_forget()
StudentPage(self.root)
elif pd_teacher:
numbers=Student_number
self.page.destroy()
self.lab3.pack_forget()
TeacherPage(self.root)
elif i>2:
showinfo(title='错误', message='密码三次输入错误,此次登录被终止!')
self.root.destroy()
else:
i+=1
showinfo(title='错误', message='账号或密码错误!')
except:
showinfo(title='错误',message='输入错误,请重新输入!')
def signup(self):
'''
学生注册页面
1:新建一个置于顶层的窗口
2:将布局控件放入
3:每个窗口的控件布局必须是一致的,place(),grid(),pack()中的一种
'''
def insert_sql():
'''
添加学生
1:获取学生姓名,年龄,学号,密码
2:将获取到的账号与数据库文件配对,查看是否存在相同学号,如不存在,将学生插入数据库文件,存在则提示修改账户名
异常捕获:信息未填写
'''
try:
age = self.new_age.get()
number = self.new_number.get()
name = self.new_name.get()
pw = self.new_pw.get()
if len(number) < 12:
showinfo(title='提示', message='学号为12位的数字,请重新输入!')
else:
XWC=user_showdb(number)#先判断账号是否存在于学生或者教师数据库
SHB=teacher_showdb(number)
if XWC == None and SHB == None:
user_insertData(number,name,pw,age)
showinfo(title='提示', message='注册成功')
self.window_sign_up.destroy()
else:
showinfo(title='提示',message='学号重复,注册失败,请修改学号!')
except:
showinfo(title='错误',message='未知错误,请重新输入!')
self.window_sign_up = Toplevel(self.root)
winWidth = 300
winHeight = 200
self.window_sign_up.title('注册窗口')
screenWidth = self.window_sign_up.winfo_screenwidth()
screenHeight = self.window_sign_up.winfo_screenheight()
x = int((screenWidth - winWidth) / 2)
y = int((screenHeight - winHeight) / 2)
# 设置窗口初始位置在屏幕居中
self.window_sign_up.geometry("%sx%s+%s+%s" % (winWidth, winHeight, x-50, y-50))
# 设置窗口宽高固定
self.window_sign_up.resizable(0, 0)
self.new_name = StringVar()
Label(self.window_sign_up, text='姓名: ').place(x=10, y=10)
entry_new_name = Entry(self.window_sign_up, textvariable=self.new_name)
entry_new_name.place(x=130, y=10)
self.new_age= StringVar()
Label(self.window_sign_up, text='年龄: ').place(x=10, y=50)
entry_usr_age = Entry(self.window_sign_up, textvariable=self.new_age)
entry_usr_age.place(x=130, y=50)
self.new_number = StringVar()
Label(self.window_sign_up, text='学号: ').place(x=10, y=90)
entry_student_number = Entry(self.window_sign_up, textvariable=self.new_number)
entry_student_number.place(x=130, y=90)
self.new_pw = StringVar()
Label(self.window_sign_up, text='密码: ').place(x=10, y=130)
entry_usr_pw = Entry(self.window_sign_up, textvariable=self.new_pw, show='*')
entry_usr_pw.place(x=130, y=130)
sign_up = Button(self.window_sign_up, text='注册', command=insert_sql)
sign_up.place(x=237, y=160)
class StudentPage(object):
def __init__(self, master=None):
self.root = master #定义内部变量root
self.root.geometry('%dx%d' % (650, 400)) #设置窗口大小
self.root.resizable(0,0) #防止用户调整尺寸
self.createPage()
def createPage(self):
self.menuPage = MenuFrame(self.root) # 创建不同Frame
# self.menuPage.pack() #默认显示界面
class MenuFrame(Frame): # 继承Frame类
def __init__(self, master=None):
Frame.__init__(self, master)
self.root = master #定义内部变量root
self.createPage()
def createPage(self):
global numbers
strs="欢迎您!学号为:%s 的同学!"%numbers
Label(self.root, text=strs).place(x=210, y=0)
Button(self.root, text='查看个人成绩单', command=self.print_ach,width=20,height=10).place(x=150, y=95)
Button(self.root, text='修改个人密码',command=self.change_pw,width=20,height=10).place(x=350, y=95)
Button(self.root, text='导出个人成绩单为Excel表格',command=self.ach_dao_xls,width=25).place(x=230, y=295)
def ach_dao_xls(self):
try:
global numbers
a=achievement_showdb(numbers)
a=tuple(a)
b=achievement_lie_name()
c=[]
c.append(tuple(b))
c.append(a)
def w_excel(res):
book = xlwt.Workbook(encoding='utf-8') #新建一个excel
sheet = book.add_sheet('sheet1') #新建一个sheet页
for row in range(0,len(res)):
for col in range(0,len(res[row])):
sheet.write(row,col,res[row][col])
row+=1
col+=1
book.save('%s_student_achievement.csv'%numbers)
print("导出成功!")
w_excel(c)
showinfo(title='确认', message='导出成功!')
except:
showinfo(title='错误', message='未知错误,请重新导出!')
def print_ach(self):
global numbers
self.ach = Toplevel(self.root)
self.ach.title('个人成绩单')
winWidth = 300
winHeight = 200
screenWidth = self.ach.winfo_screenwidth()
screenHeight = self.ach.winfo_screenheight()
x = int((screenWidth - winWidth) / 2)
y = int((screenHeight - winHeight) / 2)
# 设置窗口初始位置在屏幕居中
self.ach.geometry("%sx%s+%s+%s" % (winWidth, winHeight, x, y))
# 设置窗口宽高固定
self.ach.resizable(0, 0)
b=achievement_lie_name()
a=achievement_showdb(numbers)
a=list(a)
for i,j in enumerate(a):
if i>=2:
strs=b[i]+":"+str(j)
Label(self.ach, text=strs).pack()
def change_pw(self):
def sure_change():
global numbers
try:
New_pw=self.new_pw.get()
#print(User_id)
New_pws=self.new_pws.get()
#print(User_pw)
if New_pw==New_pws:
user_alter_pw(numbers,New_pw)
print("学号为%s的学生已修改密码,新密码为:%s"%(numbers,New_pw))
showinfo(title='提示',message='密码已修改,请重启软件重新登录!')
self.root.destroy()
else:
showinfo(title='错误',message='两次密码不一致,请重新输入!')
except:
showinfo(title='错误',message='未知错误,请重新输入!')
global numbers
self.change_pw = Toplevel(self.root)
self.change_pw.title('修改密码')
winWidth = 230
winHeight = 210
screenWidth = self.change_pw.winfo_screenwidth()
screenHeight = self.change_pw.winfo_screenheight()
x = int((screenWidth - winWidth) / 2)
y = int((screenHeight - winHeight) / 2)
# 设置窗口初始位置在屏幕居中
self.change_pw.geometry("%sx%s+%s+%s" % (winWidth, winHeight, x, y))
# 设置窗口图标
# root.iconbitmap("./image/icon.ico")
# 设置窗口宽高固定
self.change_pw.resizable(0, 0)
self.new_pw = StringVar()
self.new_pws = StringVar()
Label(self.change_pw, text='请输入新密码').place(x=110, y=0)
Label(self.change_pw, text='新密码: ').place(x=25, y=20)
Entry(self.change_pw, textvariable=self.new_pw, show='*').place(x=70, y=20)
Label(self.change_pw, text='重复新密码: ').place(x=0, y=50)
Entry(self.change_pw, textvariable=self.new_pws, show='*').place(x=70, y=50)
Button(self.change_pw, text='确认修改',command=sure_change).place(x=90, y=90)
class TeacherPage(object):
def __init__(self, master=None):
self.root = master #定义内部变量root
self.root.geometry('%dx%d' % (650, 400)) #设置窗口大小
self.root.resizable(0,0) #防止用户调整尺寸
self.createPage()
def createPage(self):
self.teacher_menuPage = teacher_MenuFrame(self.root) # 创建不同Frame
# self.menuPage.pack() #默认显示界面
class teacher_MenuFrame(Frame): # 继承Frame类
def __init__(self, master=None):
Frame.__init__(self, master)
self.root = master #定义内部变量root
self.createPage()
def createPage(self):
global numbers
strs="欢迎您!教师号为:%s 的老师!"%numbers
Label(self.root, text=strs).place(x=210, y=0)
Button(self.root, text='查看学生成绩单', command=self.print_student_ach,width=20,height=10).place(x=150, y=95)
Button(self.root, text='修改学生成绩',command=self.change_ach,width=20,height=10).place(x=350, y=95)
def change_ach(self):
def add_new_subject():
def sure_add():
try:
Subject_name=self.subject_name.get()
achievement_insertData(Subject_name)
showinfo(title='确认', message='添加成功!')
self.add_menu.destroy()
except:
showinfo(title='错误', message='未知错误,请重新修改!')
self.add_menu.destroy()
self.change_menu.destroy()
self.add_menu = Toplevel(self.root)
self.add_menu.title('修改学生成绩')
winWidth = 200
winHeight = 200
screenWidth = self.add_menu.winfo_screenwidth()
screenHeight = self.add_menu.winfo_screenheight()
x = int((screenWidth - winWidth) / 2)
y = int((screenHeight - winHeight) / 2)
# 设置窗口初始位置在屏幕居中
self.add_menu.geometry("%sx%s+%s+%s" % (winWidth, winHeight, x, y))
# 设置窗口宽高固定
self.add_menu.resizable(0, 0)
self.subject_name=StringVar()
Label(self.add_menu, text='科目名: ').place(x=10, y=30)
Entry(self.add_menu, textvariable=self.subject_name).place(x=50, y=30)
Button(self.add_menu, text='确认添加',command=sure_add).place(x=80, y=80)
def sure_change():
try:
Student_number=self.student_number.get()
Student_ach=self.student_ach.get()
Subject_name=self.comvalue.get()
if Student_ach >100 or Student_ach < 0:
showinfo(title='错误', message='成绩数值错误,请重新修改!')
else:
achievement_alter(Student_number,Subject_name,Student_ach)
showinfo(title='确认', message='修改成功!')
self.change_menu.destroy()
except:
showinfo(title='错误', message='未知错误,请重新修改!')
self.change_menu.destroy()
self.change_menu = Toplevel(self.root)
self.change_menu.title('修改学生成绩')
winWidth = 550
winHeight = 300
screenWidth = self.change_menu.winfo_screenwidth()
screenHeight = self.change_menu.winfo_screenheight()
x = int((screenWidth - winWidth) / 2)
y = int((screenHeight - winHeight) / 2)
# 设置窗口初始位置在屏幕居中
self.change_menu.geometry("%sx%s+%s+%s" % (winWidth, winHeight, x, y))
# 设置窗口宽高固定
self.change_menu.resizable(0, 0)
def go(*args):
#处理事件,*args表示可变参数
print(comboxlist.get())
return comboxlist.get()#打印选中的值
self.comvalue=StringVar()#窗体自带的文本,新建一个值
comboxlist=ttk.Combobox(self.change_menu,textvariable=self.comvalue) #初始化
achievement_lie_name()#获取科目列表
b=achievement_lie_name()
# print(b)
a=[]
j=0
for i in b:
if j>=2:
a.append(i)
j+=1
a=tuple(a)
# print(a)
comboxlist["values"]=a
comboxlist.current(0) #选择第一个
comboxlist.bind("<<ComboboxSelected>>",go) #绑定事件,(下拉列表框被选中时,绑定go()函数)
Label(self.change_menu, text="请选择科目").place(x=140, y=50)
comboxlist.place(x=230, y=50)
Label(self.change_menu, text="如果没有科目").place(x=140, y=98)
Button(self.change_menu, text='请添加科目',command=add_new_subject,width=22).place(x=230, y=95)
self.student_number = StringVar()
self.student_ach = IntVar()
Label(self.change_menu, text='学号: ').place(x=180, y=150)
Entry(self.change_menu, textvariable=self.student_number).place(x=220, y=150)
Label(self.change_menu, text='成绩(0~100): ').place(x=135, y=200)
Entry(self.change_menu, textvariable=self.student_ach).place(x=220, y=200)
Button(self.change_menu, text='确认修改',command=sure_change).place(x=250, y=250)
def print_student_ach(self):
def dao_subject_ach():
try:
b=achievement_lie_name()
chiose=""
Subject_name=self.comvalue.get()
V=self.v.get()
if V==0:
chiose=None
if V==1:
chiose="desc"
all_str=achievement_paixu(Subject_name,chiose)
all_str.insert(0,b)
def w_excel(res):
book = xlwt.Workbook(encoding='utf-8') #新建一个excel
sheet = book.add_sheet('sheet1') #新建一个sheet页
for row in range(0,len(res)):
for col in range(0,len(res[row])):
sheet.write(row,col,res[row][col])
row+=1
col+=1
book.save('%s排序成绩.xls'%Subject_name)
print("导出成功!")
w_excel(all_str)
showinfo(title='确认', message='导出成功!')
except:
showinfo(title='错误', message='未知错误,请重新导出!')
def paixu():
chiose=""
Subject_name=self.comvalue.get()
V=self.v.get()
if V==0:
chiose=None
if V==1:
chiose="desc"
self.teacher_menu = Toplevel(self.root)
self.teacher_menu.title('学生成绩单')
winWidth = 650
winHeight = 400
screenWidth = self.teacher_menu.winfo_screenwidth()
screenHeight = self.teacher_menu.winfo_screenheight()
x = int((screenWidth - winWidth) / 2)
y = int((screenHeight - winHeight) / 2)
# 设置窗口初始位置在屏幕居中
self.teacher_menu.geometry("%sx%s+%s+%s" % (winWidth, winHeight, x-50, y-50))
# 设置窗口宽高固定
self.teacher_menu.resizable(0, 0)
S=Scrollbar(self.teacher_menu)
T=Text(self.teacher_menu,width=400)
S.pack(side=RIGHT,fill=Y)
T.pack(side=LEFT,fill=Y)
S.config(command=T.yview)
T.config(yscrollcommand=S.set)
# insert的第一个参数为索引;第二个为添加的内容
all_str=achievement_paixu(Subject_name,chiose)
b=achievement_lie_name()
strss=" 学号"+" |"+" 姓名"+" |"
for i,j in enumerate(b):
if i>=2:
strss+=" "+str(j)+" |"
strss+='\n\n'
T.insert(END,strss)
for i in all_str:
strs=""
for j in i:
strs=strs+" "+str(j)+" |"
strs+="\n\n"
T.insert(END,strs)
T.pack()
self.student_ach_menu = Toplevel(self.root)
self.student_ach_menu.title('按科目升/降序查看成绩')
winWidth = 300
winHeight = 300
screenWidth = self.student_ach_menu.winfo_screenwidth()
screenHeight = self.student_ach_menu.winfo_screenheight()
x = int((screenWidth - winWidth) / 2)
y = int((screenHeight - winHeight) / 2)
# 设置窗口初始位置在屏幕居中
self.student_ach_menu.geometry("%sx%s+%s+%s" % (winWidth, winHeight, x, y))
# 设置窗口图标
# root.iconbitmap("./image/icon.ico")
# 设置窗口宽高固定
self.student_ach_menu.resizable(0, 0)
def go(*args):
#处理事件,*args表示可变参数
print(comboxlist.get())
return comboxlist.get()#打印选中的值
self.comvalue=StringVar()#窗体自带的文本,新建一个值
comboxlist=ttk.Combobox(self.student_ach_menu,textvariable=self.comvalue) #初始化
achievement_lie_name()#获取科目列表
b=achievement_lie_name()
# print(b)
a=[]
j=0
for i in b:
if j>=2:
a.append(i)
j+=1
a=tuple(a)
comboxlist["values"]=a
comboxlist.current(0) #选择第一个
comboxlist.bind("<<ComboboxSelected>>",go) #绑定事件,(下拉列表框被选中时,绑定go()函数)
Label(self.student_ach_menu, text="请选择科目:").place(x=10, y=35)
comboxlist.place(x=80, y=35)
self.v= IntVar()
r1 = Radiobutton(self.student_ach_menu, variable=self.v, value=0, text="升序")
r2 = Radiobutton(self.student_ach_menu, variable=self.v, value=1, text="降序")
self.v.set(0)
r1.place(x=244, y=25)
r2.place(x=244, y=45)
Button(self.student_ach_menu, text='查看学生成绩单', command=paixu,width=20,height=3).place(x=80, y=105)
Button(self.student_ach_menu, text='导出某科升序/降序学生成绩单', command=dao_subject_ach,width=30,height=3).place(x=44, y=175)
成绩表操作界面
# -*- coding:utf-8 -*-
import sqlite3
from student_info_sql import *
# 打开成绩数据库
def achievement_opendb():
conn = sqlite3.connect("student.db")
cur = conn.execute("""create table if not exists student_achievement(
student_number varchar(12),
student_name varchar(10))""")
return cur, conn
#查询所有列名
def achievement_lie_name():
hel = achievement_opendb()
cur = hel[1].cursor() #设置游标
cur.execute("select * from student_achievement")
col_name_list = [tuple[0] for tuple in cur.description]
return col_name_list
cur.close()
#查询学生成绩全部信息
def achievement_slectTable():
hel = achievement_opendb()
cur = hel[1].cursor()
cur.execute("select * from student_achievement")
res = cur.fetchall()
return res
cur.close()
# 往成绩数据库中添加新的一列科目成绩
def achievement_insertData(subject_name):
hel = achievement_opendb()
hel[1].execute("alter table student_achievement add column "+subject_name+" int")
hel[1].commit()
hel[1].close()
# 往成绩数据库中添加学生跟学生信息表同步更新
def achievement_infoData(number,name):
hel = achievement_opendb()
hel[1].execute("insert into student_achievement(student_number,student_name)values (?,?)",(number,name))
hel[1].commit()
hel[1].close()
# 按某科排序输出 默认升序 添加desc为降序
def achievement_paixu(subject_name,desc):
if desc==None:
desc=""
else:
desc=desc
hel = achievement_opendb()
cur = hel[1].cursor()
cur.execute("select * from student_achievement order by "+subject_name+" "+desc)
res = cur.fetchall() #fetchall()函数是查询所有的元素,在游标的格式下
cur.close()
return res
#查询个人成绩信息
def achievement_showdb(number):
hel = achievement_opendb()
cur = hel[1].cursor()
cur.execute("select * from student_achievement where student_number="+number)
res = cur.fetchone() #fatchone()函数是擦汗寻某一个对应行的元素
cur.close()
return res
# 删除成绩数据库中的全部内容
def achievement_delalldb():
hel = achievement_opendb() # 返回游标conn
hel[1].execute("delete from student_achievement")
print("删库跑路XWC我最帅")
hel[1].commit()
hel[1].close()
# 删除成绩数据库中的指定学生内容跟学生信息表同步更新
def achievement_deldb(number):
hel = achievement_opendb() # 返回游标conn
hel[1].execute("delete from student_achievement where student_number="+number)
print("已删除学号为%s 学生的成绩单" %number)
hel[1].commit()
hel[1].close()
# 修改成绩数据库的个人某科成绩
def achievement_alter(number,subject_name,ach):
hel = achievement_opendb()
hel[1].execute("update student_achievement set %s = %s where student_number=%s"%(subject_name,ach,number))
hel[1].commit()
hel[1].close()
学生表操作界面
# -*- coding:utf-8 -*-
import sqlite3
from student_achievement_sql import *
# 打开学生数据库
def user_opendb():
conn = sqlite3.connect("student.db")
cur = conn.execute("""create table if not exists student_info(
id integer PRIMARY KEY autoincrement,
student_number varchar(12),
student_name varchar(10),
student_passworld varchar(128),
age varchar(2))""")
return cur, conn
#查询所有列名
def user_lie_name():
hel = user_opendb()
cur = hel[1].cursor()
cur.execute("select * from student_info")
col_name_list = [tuple[0] for tuple in cur.description]
return col_name_list
cur.close()
#查询学生全部信息
def user_slectTable():
hel = user_opendb()
cur = hel[1].cursor()
cur.execute("select * from student_info")
res = cur.fetchall()
#for line in res:
#for h in line:
#print(h),
#print(line)
return res
cur.close()
# 往学生数据库中添加内容
def user_insertData(number,name,pw,age):
achievement_infoData(number,name)
hel = user_opendb()
hel[1].execute("insert into student_info(student_number,student_name, student_passworld,age)values (?,?,?,?)",(number,name,pw,age))
hel[1].commit()
hel[1].close()
#查询学生个人信息
def user_showdb(number):
hel = user_opendb()
cur = hel[1].cursor()
cur.execute("select * from student_info where student_number="+number)
res = cur.fetchone()
cur.close()
return res
# 删除学生数据库中的全部内容
def user_delalldb():
achievement_delalldb()
hel = user_opendb() # 返回游标conn
hel[1].execute("delete from student_info")
print("删库跑路XWC我最帅")
hel[1].commit()
hel[1].close()
# 删除学生数据库中的指定内容
def user_deldb(number):
achievement_deldb(number)
hel = user_opendb() # 返回游标conn
hel[1].execute("delete from student_info where student_number="+number)
print("已删除学号为 %s 学生" %number)
hel[1].commit()
hel[1].close()
# 修改学生数据库的内容
def user_alter(number,name,pw,age):
hel = user_opendb()
hel[1].execute("update student_info set student_name=?, student_passworld= ?,age=? where student_number="+number,(name,pw,age))
hel[1].commit()
hel[1].close()
# 修改学生数据库密码的内容
def user_alter_pw(number,pw):
hel = user_opendb()
hel[1].execute("update student_info set student_passworld= %s where student_number=%s"%(pw,number))
hel[1].commit()
hel[1].close()
# 登录查询学生数据
def user_slect_number_pw(number,pw):
hel = user_opendb()
cur = hel[1].cursor()
cur.execute("select * from student_info where student_number="+number+" and student_passworld= "+pw)
hel[1].commit()
for row in cur:
if row:
return True
else:
return False
cur.close()
hel[1].close()
老师表操作界面
# -*- coding:utf-8 -*-
import sqlite3
# 打开教师数据库
def teacher_opendb():
conn = sqlite3.connect("student.db")
cur = conn.execute("""create table if not exists teacher_info(
id integer PRIMARY KEY autoincrement,
teacher_number varchar(12),
teacher_name varchar(10),
teacher_passworld varchar(128),
age varchar(2))""")
return cur, conn
#查询所有列名
def teacher_lie_name():
hel = teacher_opendb()
cur = hel[1].cursor()
cur.execute("select * from teacher_info")
col_name_list = [tuple[0] for tuple in cur.description]
return col_name_list
cur.close()
#查询教师全部信息
def teacher_slectTable():
hel = teacher_opendb()
cur = hel[1].cursor()
cur.execute("select * from teacher_info")
res = cur.fetchall()
#for line in res:
#for h in line:
#print(h),
#print(line)
return res
cur.close()
# 往教师数据库中添加内容
def teacher_insertData(number,name,pw,age):
hel = teacher_opendb()
hel[1].execute("insert into teacher_info(teacher_number,teacher_name, teacher_passworld,age)values (?,?,?,?)",(number,name,pw,age))
hel[1].commit()
hel[1].close()
#查询教师个人信息
def teacher_showdb(number):
hel = teacher_opendb()
cur = hel[1].cursor()
cur.execute("select * from teacher_info where teacher_number="+number)
res = cur.fetchone()
cur.close()
return res
# 删除教师数据库中的全部内容
def teacher_delalldb():
hel = teacher_opendb() # 返回游标conn
hel[1].execute("delete from teacher_info")
print("删库跑路XWC我最帅")
hel[1].commit()
hel[1].close()
# 删除教师数据库中的指定内容
def teacher_deldb(number):
hel = teacher_opendb() # 返回游标conn
hel[1].execute("delete from teacher_info where teacher_number="+number)
print("已删除教师号为 %s 教师" %number)
hel[1].commit()
hel[1].close()
# 修改教师数据库的内容
def teacher_alter(number,name,pw,age):
hel = teacher_opendb()
hel[1].execute("update teacher_info set teacher_name=?, teacher_passworld= ?,age=? where teacher_number="+number,(name,pw,age))
hel[1].commit()
hel[1].close()
# 修改教师数据库密码的内容
def teacher_alter_pw(number,pw):
hel = teacher_opendb()
hel[1].execute("update teacher_info set teacher_passworld= %s where teacher_number=%s"%(pw,number))
hel[1].commit()
hel[1].close()
# 登录查询教师数据
def teacher_slect_number_pw(number,pw):
hel = teacher_opendb()
cur = hel[1].cursor()
cur.execute("select * from teacher_info where teacher_number="+number+" and teacher_passworld= "+pw)
hel[1].commit()
for row in cur:
if row:
return True
else:
return False
cur.close()
hel[1].close()