(以下是一个关于python的学生管理系统的应用程序介绍,长按收藏有惊喜哦!)
目录
项目介绍
流程图
自述
个人观点
运行截图
文件结构
代码资源
这个项目主要包含了GUI界面和后台程序,该项目是通过文件存储的方式来保存学生信息的,主要包含的操作有学生信息的增删改查功能,还有用户的登录功能,涵盖的信息有学生的学号 姓名 性别 年龄 学院 专业,涉及的课程内容有GUI界面,类和对象,方法,字典,列表,文件操作,获取异常等。
登录,通过输入管理员的账号密码来实现登录操作。具体实现的过程是通过输入框输入账号密码,然后使用get方法来获取各个输入框的值,再用if语句判断获取的值是否等于自己设置的账号密码,如果相等,则登录成功,进入主界面。
添加学生信息,通过输入学生的个人信息,即学号、姓名、年龄、学院、专业,来实现添加学生的操作。具体实现的过程是用户通过输入框输入学号、姓名、年龄、学院、专业,然后使用get方法来获取各个输入框的内容,判断学号是否重复,如果学号不重复,则把信息赋值到列表中,然后通过列表的形式把值赋给字典,最后把列表写入文件。
删除学生信息,通过输入学生的学号来实现删除学生的操作。具体实现的过程是用户通过输入框输入学号,然后通过get方法来获取输入框的学号;再读取文件,把文件转换成字典的方式,通过字典的键值对来判断学号是否存在,如果存在则把用户输入信息的匹配数据所在行删除。
修改学生信息,通过输入学生的学号来实现对学生信息的修改。具体实现的过程是用户通过输入框输入学号,然后通过get方法来获取输入框的学号;打开文件并读取文件中的内容,将内容转换为字典的格式,检查字典中是否存在该学号;如果存在则进入修改页面,输入信息到输入框,通过get方法获取输入框的学号,然后通过键值对的方法来写入字典,最后保存到文件中。
查询学生信息,通过输入学生的学号来实现对学生信息的查询。具体实现的过程是用户通过输入框输入学号,然后通过get方法来获取输入框的学号;打开文件并读取文件中的内容,将内容转换为字典的格式,检查字典是否存在该学号;如果存在,则通过表格的方式来输出信息,最后输出该学生信息,显示在页面。
显示所有学生信息,具体实现的过程是通过读取文件内容,通过total方法统计并输出汇总人数,然后通过表格的方式来定义表头和内容格式,最后把所有学生信息全部有序地显示在表格上。
退出,点击退出或者Esc键,再点击“是”退出程序。
学生信息管理系统是比较普通的题材,因为本人基础不扎实,所以选择了这一题材,在项目运作的过程中,遇到的问题比较多,有的也比较难解决,有时候一个问题要几天才能解决,甚至根本解决不了,这个时候还要请求老师的帮忙,这些天来还得感谢老师的帮忙,我才能完整的完成这个项目。刚开始做这个项目,并没有百分百的把握,因为之前自学过一点python,发现太难就没有学下去的动力,但是项目做到一半,发现python还是挺有趣的一门语言。本来刚开始是只做了主界面,没有登录界面的,但是听了老师的建议之后,还是加了登录界面进去,然后发现有了登录界面的话,看起来好很多。
最主要的问题就是调试,因为调试的过程真的非常不容易,需要使用print语句和断点的方法来对程序进行细心并且耐心地调试,有时候if,for,while,try catch语句混合起来太多就会出现异常报错,或者出现逻辑上的问题,而导致某个功能出现较严重的问题,甚至有时候只是因为一个小小的break没有添加或者缩进多一个或少一个就出现了大问题。
后期可以增加用户二次确认提示,主界面时间显示,完善显示所有学生信息界面的格式,以及增加用户注册功能等。
优点:
系统功能齐全,界面简洁美观,操作简单。
缺点:
整体代码冗余量较大,功能少,细节问题处理不到位,如删除没有给予二次确认,修改操作点击X会出现大问题,也就是可能导致后台数据清空或者删除该学生,还有就是基本没有使用到类这个知识点,而且登录页面没有注册功能,只能在代码中设置账号密码,界面不够好看等问题。
main.py
import os
from tkinter import *
from tkinter import ttk
from tkinter.messagebox import showerror, showinfo, askquestion
from tool import *
# 添加界面
def add():
add_tk = Tk()
add_tk.title('')
Center.show_center(add_tk)
add_tk.resizable(False, False) # 不可调整大小
add_tk.iconphoto(False, PhotoImage(file="../image/icon.png"))
add_word = Label(add_tk, text='添加学生信息', font=('华文新魏', 20))
add_word.place(relx=0.3, rely=0.05, relwidth=0.4, relheight=0.05)
# 字样
no_label = Label(add_tk, text='学号')
name_label = Label(add_tk, text='姓名')
sex_label = Label(add_tk, text='性别')
age_label = Label(add_tk, text='年龄')
academy_label = Label(add_tk, text='学院')
major_label = Label(add_tk, text='专业')
no_label.place(relx=0.165, rely=0.17, relwidth=0.2, relheight=0.05)
name_label.place(relx=0.165, rely=0.27, relwidth=0.2, relheight=0.05)
sex_label.place(relx=0.165, rely=0.37, relwidth=0.2, relheight=0.05)
age_label.place(relx=0.165, rely=0.47, relwidth=0.2, relheight=0.05)
academy_label.place(relx=0.165, rely=0.57, relwidth=0.2, relheight=0.05)
major_label.place(relx=0.165, rely=0.67, relwidth=0.2, relheight=0.05)
no = StringVar()
name = StringVar()
sex = StringVar()
age = IntVar()
academy = StringVar()
major = StringVar()
# 输入框
no_input = ttk.Entry(add_tk, textvariable=no, font=('Microsoft yahei', 10))
name_input = ttk.Entry(add_tk, textvariable=name, font=('Microsoft yahei', 10))
sex_input1 = ttk.Radiobutton(add_tk, text='男', variable=sex, value='男')
sex_input2 = ttk.Radiobutton(add_tk, text='女', variable=sex, value='女')
age_input = ttk.Entry(add_tk, textvariable=age, font=('Microsoft yahei', 10))
age_input.delete(0, 'end') # 去除默认值 0
academy_values = ['法学院', '会计学院', '外国语学院', '管理学院', '经济学院', '艺术设计学院', '现代信息产业学院',
'信息技术与工程学院', '国际学院']
academy_input = ttk.Combobox(add_tk, textvariable=academy, values=academy_values, font=('Microsoft yahei', 10))
major_input = ttk.Entry(add_tk, textvariable=major, font=('Microsoft yahei', 10))
no_input.place(relx=0.335, rely=0.17, relwidth=0.4, relheight=0.05)
name_input.place(relx=0.335, rely=0.27, relwidth=0.4, relheight=0.05)
sex_input1.place(relx=0.335, rely=0.37)
sex_input2.place(relx=0.435, rely=0.37)
age_input.place(relx=0.335, rely=0.47, relwidth=0.4, relheight=0.05)
academy_input.place(relx=0.335, rely=0.57, relwidth=0.4, relheight=0.05)
major_input.place(relx=0.335, rely=0.67, relwidth=0.4, relheight=0.05)
# 返回按钮
back_btn = Button(add_tk, text='返回', bg='gainsboro', activebackground='gainsboro', relief=GROOVE,
command=lambda: [add_tk.destroy(), main()])
back_btn.place(relx=0.2, rely=0.8, relwidth=0.15, relheight=0.05)
# 将信息写入文件
def add_data():
stu_if_dict = {}
student_no = no.get()
student_name = name.get()
student_sex = sex.get()
student_age = age.get()
student_academy = academy.get()
student_major = major.get()
# print(student_no, student_name, student_sex, student_age, student_academy, student_major)
# a+ 以附加读写方式打开
f = open(PATH, 'a+', encoding='utf-8')
f.readlines()
# r只读 防止后面追加信息
# 获取异常防止文件不存在
try:
w_file = open(PATH, 'r', encoding='utf-8')
stu_file = w_file.readlines()
for item in stu_file:
stu_if_dict = dict(eval(item))
# print(stu_if_dict)
except FileNotFoundError: # 文件不存在
# 字典赋空
stu_if_dict = []
if stu_if_dict["学号"] != student_no:
# stu_if_dict["学号"] == student_no
# print("====" + stu_if_dict["学号"])
# 对输入内容限制
if len(student_no) != 0 and len(student_name) != 0 and len(student_sex) != 0 and \
student_age != '' and len(student_academy) != 0 and len(student_major) != 0:
print('学号:' + student_no)
print('姓名:' + student_name)
print('性别:' + student_sex)
print('年龄:' + f'{student_age}')
print('学院:' + student_academy)
print('专业:' + student_major)
# 将录入的学生信息保存到字典当中
student = {'学号': student_no, '姓名': student_name, '性别': student_sex, '年龄': student_age,
'学院': student_academy, '专业': student_major}
# print(student)
# 将字典添加到列表中
student_list = [student]
# 保存到文件
Save_txt.save(student_list)
showinfo(title='提示', message='添加成功!')
else:
showinfo(title='提示', message='请输入信息!')
else:
showerror(title='提示', message='该学号已存在!')
# print('添加失败!')
# 保存按钮
save_btn = Button(add_tk, text='保存', bg='lightskyblue', activebackground='lightskyblue', relief=GROOVE,
command=lambda: [add_data(), add_tk.destroy(), main()])
save_btn.place(relx=0.65, rely=0.8, relwidth=0.15, relheight=0.05)
# 删除界面
def delete():
delete_tk = Tk()
delete_tk.title('')
Center.show_center(delete_tk)
delete_tk.resizable(False, False)
delete_tk.iconphoto(False, PhotoImage(file="../image/icon.png"))
delete_word = Label(delete_tk, text='删除学生信息', font=('华文新魏', 20))
delete_word.place(relx=0.3, rely=0.1, relwidth=0.4, relheight=0.05)
delete_label = Label(text='请输入你要删除的学生学号:', font=('黑体', 13))
delete_label.place(relx=0.2, rely=0.3, relwidth=0.6, relheight=0.1)
no = StringVar()
# 输入框
no_input = ttk.Entry(delete_tk, textvariable=no, font=('Microsoft yahei', 10))
no_input.place(relx=0.3, rely=0.4, relwidth=0.4, relheight=0.05)
# 返回按钮
back_btn = Button(delete_tk, text='返回', bg='gainsboro', activebackground='gainsboro', relief=GROOVE,
command=lambda: [delete_tk.destroy(), main()])
back_btn.place(relx=0.2, rely=0.8, relwidth=0.15, relheight=0.05)
# 将文件中的所在行信息删除
def del_info():
student_no = no.get()
# print(student_no)
if len(student_no) != 0:
if os.path.exists(PATH):
file = open(PATH, 'r', encoding='utf-8')
student_old = file.readlines()
else:
# 赋空列表
student_old = []
flag = False # 标记是否删除
if student_old:
w_file = open(PATH, 'w', encoding='utf-8')
d = {}
for item in student_old:
d = dict(eval(item)) # 将字符串转成字典
if d['学号'] != student_no:
w_file.write(str(d) + '\n')
else:
flag = True
if flag:
print(f"学号为{student_no}的学生已被删除!")
showinfo(title='提示', message='删除成功!')
else:
showerror(title='提示', message='没有找到该学号的学生信息!')
else:
# print('无学生信息!')
showerror(title='提示', message='后台无数据!')
elif len(student_no) == 0:
showinfo(title='提示', message='请输入学号!')
# # 删除二次确认
# def delete_if():
# delete_result = askquestion(title='警告', message="确认删除?")
# # print('askquestion: %s'.rjust(18) % delete_result) # 查看返回值
# if delete_result == "yes":
# del_info()
# else:
# pass
# 删除按钮
delete_btn = Button(delete_tk, text='删除', bg='lightskyblue', activebackground='lightskyblue', relief=GROOVE,
command=lambda: [del_info(), delete_tk.destroy(), main()])
delete_btn.place(relx=0.65, rely=0.8, relwidth=0.15, relheight=0.05)
# 修改界面
def revise():
revise_tk = Tk()
revise_tk.title('')
Center.show_center(revise_tk)
revise_tk.resizable(False, False)
revise_tk.iconphoto(False, PhotoImage(file="../image/icon.png"))
revise_word = Label(revise_tk, text='修改学生信息', font=('华文新魏', 20))
revise_word.place(relx=0.3, rely=0.1, relwidth=0.4, relheight=0.05)
revise_label = Label(revise_tk, text='请输入你要修改的学生学号:', font=('黑体', 13))
revise_label.place(relx=0.2, rely=0.3, relwidth=0.6, relheight=0.1)
no = StringVar()
# 输入框
no_input = ttk.Entry(revise_tk, textvariable=no, font=('Microsoft yahei', 10))
no_input.place(relx=0.3, rely=0.4, relwidth=0.4, relheight=0.05)
# 返回按钮
back_btn = Button(revise_tk, text='返回', bg='gainsboro', activebackground='gainsboro', relief=GROOVE,
command=lambda: [revise_tk.destroy(), main()])
back_btn.place(relx=0.2, rely=0.8, relwidth=0.15, relheight=0.05)
def modify():
student_no = no.get()
if len(student_no) == 0:
showinfo(title='提示', message='请输入学号!')
# print(student_no)
if os.path.exists(PATH):
rfile = open(PATH, 'r', encoding='utf-8')
student_old = rfile.readlines()
# 获取文件全部内容
# file_obj = open(filename, encoding='utf-8')
# file_contents = file_obj.read()
# print(file_contents.rstrip())
else:
return
w_file = open(PATH, 'w', encoding='utf-8')
for item in student_old:
d = dict(eval(item))
if d['学号'] == student_no:
# print('找到该学号的学生信息!')
# print(d["学号"], d["姓名"], d["性别"], d["年龄"], d["学院"], d["专业"])
while True:
try:
revise_word.place(relx=0.3, rely=0.05, relwidth=0.4, relheight=0.05)
back_btn.destroy()
sure_btn.destroy()
no_input.destroy()
revise_label.destroy()
name_label = Label(text='姓名')
sex_label = Label(text='性别')
age_label = Label(text='年龄')
academy_label = Label(text='学院')
major_label = Label(text='专业')
name_label.place(relx=0.165, rely=0.17, relwidth=0.2, relheight=0.05)
sex_label.place(relx=0.165, rely=0.27, relwidth=0.2, relheight=0.05)
age_label.place(relx=0.165, rely=0.37, relwidth=0.2, relheight=0.05)
academy_label.place(relx=0.165, rely=0.47, relwidth=0.2, relheight=0.05)
major_label.place(relx=0.165, rely=0.57, relwidth=0.2, relheight=0.05)
name = StringVar()
age = IntVar()
sex = StringVar()
academy = StringVar()
major = StringVar()
# 输入框
name_input = ttk.Entry(revise_tk, textvariable=name, font=('Microsoft yahei', 10))
sex_input1 = ttk.Radiobutton(revise_tk, text='男', variable=sex, value='男')
sex_input2 = ttk.Radiobutton(revise_tk, text='女', variable=sex, value='女')
age_input = ttk.Entry(revise_tk, textvariable=age, font=('Microsoft yahei', 10))
age_input.delete(0, 'end') # 去除默认值 0
academy_values = ['法学院', '会计学院', '外国语学院', '管理学院', '艺术设计学院',
'现代信息产业学院', '信息技术与工程学院', '国际学院']
academy_input = ttk.Combobox(revise_tk, textvariable=academy, values=academy_values,
font=('Microsoft yahei', 10))
major_input = ttk.Entry(revise_tk, textvariable=major, font=('Microsoft yahei', 10))
name_input.place(relx=0.335, rely=0.17, relwidth=0.4, relheight=0.05)
sex_input1.place(relx=0.335, rely=0.27)
sex_input2.place(relx=0.435, rely=0.27)
age_input.place(relx=0.335, rely=0.37, relwidth=0.4, relheight=0.05)
academy_input.place(relx=0.335, rely=0.47, relwidth=0.4, relheight=0.05)
major_input.place(relx=0.335, rely=0.57, relwidth=0.4, relheight=0.05)
name_input.insert(INSERT, d["姓名"])
if d["性别"] == "男":
sex.set('男')
elif d["性别"] == "女":
sex.set('女')
else:
pass
age_input.insert(INSERT, d["年龄"])
academy_input.insert(INSERT, d["学院"])
major_input.insert(INSERT, d["专业"])
# print('------------------')
# print(name_input)
# print(age_input)
# print('------------------')
# 写入文件
def modify_to():
student_name = name.get()
student_sex = sex.get()
student_age = age.get()
student_academy = academy.get()
student_major = major.get()
# print("===" + student_name)
# print("===" + student_sex)
# print("===" + student_age)
# print("===" + student_academy)
# print("===" + student_major)
# print(len(student_name), len(student_sex), len(student_age), len(student_academy),
# len(student_major)) 所有输入框不能为空
# 'Key': Value
d['学号'] = student_no
d['姓名'] = student_name
d['性别'] = student_sex
d['年龄'] = student_age
d['学院'] = student_academy
d['专业'] = student_major
w_file.write(str(d) + '\n')
if w_file is not None:
w_file.close()
# print('修改成功!!!')
showinfo(title='提示', message='修改成功!')
tip_label = Label(revise_tk, text='Tip: 请勿关闭该窗口,否则将删除该学生信息!!!',
foreground='red')
tip_label.place(relx=0.29, rely=0.67, relwidth=0.42, relheight=0.05)
# 修改按钮
modify_btn = Button(revise_tk, text='修改', bg='lightskyblue',
activebackground='lightskyblue', relief=GROOVE,
command=lambda: [modify_to(), revise_tk.destroy(), main()])
modify_btn.place(relx=0.4, rely=0.8, relwidth=0.2, relheight=0.05)
except IOError:
showerror(title='错误', message='您的输入有误,请重新输入!!!')
# print('您的输入有误,请重新输入!!!')
else:
break
else:
# print("OK")
w_file.write(str(d) + '\n')
# break
# 确定按钮
sure_btn = Button(revise_tk, text='确定', bg='lightskyblue', activebackground='lightskyblue', relief=GROOVE,
command=lambda: [modify()])
sure_btn.place(relx=0.65, rely=0.8, relwidth=0.15, relheight=0.05)
# 查询界面
def inquire():
inquire_tk = Tk()
inquire_tk.title('')
Center.show_center(inquire_tk)
inquire_tk.resizable(False, False)
inquire_tk.iconphoto(False, PhotoImage(file="../image/icon.png"))
inquire_word = Label(inquire_tk, text='查询学生信息', font=('华文新魏', 20))
inquire_word.place(relx=0.3, rely=0.1, relwidth=0.4, relheight=0.05)
no = StringVar()
inquire_label = Label(inquire_tk, text='请输入你要查询的学生学号:', font=('黑体', 13))
inquire_label.place(relx=0.2, rely=0.3, relwidth=0.6, relheight=0.1)
no_input = ttk.Entry(inquire_tk, textvariable=no, font=('Microsoft yahei', 10))
no_input.place(relx=0.3, rely=0.4, relwidth=0.4, relheight=0.05)
# 查询学生信息
def inquire_info():
student_id = no_input.get()
# print(student_id)
if os.path.exists(PATH):
r_file = open(PATH, 'r', encoding='utf-8')
student_old = r_file.readlines()
# print(student_old)
else:
return
for item in student_old:
d = dict(eval(item))
# print('----------')
# print(d)
# print('----------')
# print('****')
# print(student_id)
# print('****')
# 判断输入框里的学号和字典里的学号是否匹配
if d['学号'] == student_id:
# print('查询到该学生信息!')
while True:
try:
no_input.destroy()
inquire_label.destroy()
inquire_container = Text(inquire_tk, relief=FLAT, font=('华文新魏', 14))
inquire_container.place(relx=0.2, rely=0.2, relwidth=0.6, relheight=0.5)
def show_student(lst):
if len(lst) == 0:
showerror(title="错误", message="后台没有学生信息,无数据显示!")
# print('没有学生信息,无数据显示!!!')
# 内容显示格式
content = '{}{}{}{}{}{}'
for item in lst:
inquire_container.insert(INSERT, content.format('学号: ' + item.get('学号') + '\n\n',
'姓名: ' + item.get('姓名') + '\n\n',
'性别: ' + item.get('性别') + '\n\n',
'年龄: ' + item.get('年龄') + '\n\n',
'学院: ' + item.get('学院') + '\n\n',
'专业: ' + item.get('专业') + '\n'
))
def show_inquire():
student_lst = []
if os.path.exists(PATH):
rfile = open(PATH, 'r', encoding='utf-8')
students = rfile.readlines()
if item in students:
student_lst.append(eval(item))
show_student(student_lst)
show_inquire()
# 写入后设置文本框为只读
inquire_container.config(state=DISABLED)
# 返回按钮
back_btn = Button(inquire_tk, text='返回', bg='gainsboro', activebackground='gainsboro',
relief=GROOVE, command=lambda: [inquire_tk.destroy(), inquire()])
back_btn.place(relx=0.2, rely=0.8, relwidth=0.15, relheight=0.05)
# 确定按钮
sure_btn = Button(inquire_tk, text='确定', bg='lightskyblue',
activebackground='lightskyblue', relief=GROOVE,
command=lambda: [inquire_tk.destroy(), main()])
sure_btn.place(relx=0.65, rely=0.8, relwidth=0.15, relheight=0.05)
except IOError:
showerror(title='提示', message='你的输入有误,请重新输入!!!')
# print('您的输入有误,请重新输入!!!')
else:
break
# print('查询成功!!!')
break
# 跳出循环
else:
showerror(title='提示', message='查找不到该学生!')
# print("查找不到该学生!!!")
# break
# 返回按钮
back_btn = Button(inquire_tk, text='返回', bg='gainsboro', activebackground='gainsboro',
relief=GROOVE, command=lambda: [inquire_tk.destroy(), main()])
back_btn.place(relx=0.2, rely=0.8, relwidth=0.15, relheight=0.05)
# 查询按钮
revise_btn = Button(inquire_tk, text='查询', bg='lightskyblue', activebackground='lightskyblue',
relief=GROOVE, command=lambda: [inquire_info()])
revise_btn.place(relx=0.65, rely=0.8, relwidth=0.15, relheight=0.05)
# 显示所有学生信息 界面
def show_all():
all_tk = Tk()
all_tk.title('')
Center.show_center(all_tk)
all_tk.resizable(False, False)
all_tk.iconphoto(False, PhotoImage(file="../image/icon.png"))
all_word = Label(all_tk, text='所有学生信息', font=('华文新魏', 20))
all_word.place(relx=0.3, rely=0.03, relwidth=0.4, relheight=0.05)
r_file = open(PATH, 'r', encoding='utf-8')
stu_total = r_file.readlines()
# print(stu_total)
total_label = Label(all_tk, text='汇总: ')
total_label.place(relx=0.05, rely=0.05)
total_text = Text(all_tk, relief=FLAT, bg='#f0f0f0')
total_text.place(relx=0.11, rely=0.057, relwidth=0.1, relheight=0.03)
total_text.insert(END, f'{len(stu_total)}')
total_text.config(state=DISABLED)
# 表格
columns = ['学号', '姓名', '性别', '年龄', '学院', '专业']
table = ttk.Treeview(all_tk, columns=columns, show='headings') # 隐藏首列
table.place(relx=0.05, rely=0.1, relwidth=0.9, relheight=0.7)
y_scroll = Scrollbar(all_tk, orient=VERTICAL, command=table.yview)
table.configure(yscrollcommand=y_scroll.set)
y_scroll.place(relx=0.95, rely=0.1, relheight=0.7)
def show_info(lst):
if len(lst) == 0:
showerror(title="错误", message="没有学生信息,无数据显示!")
# print('没有学生信息,无数据显示!!!')
return
# 定义表头
table.heading('学号', text='学号')
table.heading('姓名', text='姓名')
table.heading('性别', text='性别')
table.heading('年龄', text='年龄')
table.heading('学院', text='学院')
table.heading('专业', text='专业')
# 定义列
table.column('学号', width=100, minwidth=100, anchor=S)
table.column('姓名', width=80, minwidth=80, anchor=S)
table.column('性别', width=40, minwidth=40, anchor=S)
table.column('年龄', width=40, minwidth=40, anchor=S)
table.column('学院', width=150, minwidth=150, anchor=S)
table.column('专业', width=120, minwidth=120, anchor=S)
for item in lst:
info = [item.get('学号'),
item.get('姓名'),
item.get('性别'),
item.get('年龄'),
item.get('学院'),
item.get('专业')]
table.insert('', END, values=info)
def show():
student_lst = []
# 判断文件是否存在
if os.path.exists(PATH):
# with open(filename, 'r', encoding='utf-8') as rfile:
rfile = open(PATH, 'r', encoding='utf-8')
students = rfile.readlines()
for item in students:
student_lst.append(eval(item))
if student_lst:
show_info(student_lst)
else:
showerror(title="错误", message="没有学生信息,无数据显示!")
# print('暂未保存过数据!!!')
show()
back_btn = Button(all_tk, text='返回', bg='gainsboro', activebackground='gainsboro', relief=GROOVE,
command=lambda: [all_tk.destroy(), main()])
back_btn.place(relx=0.2, rely=0.875, relwidth=0.15, relheight=0.05)
# ======================================
# 主界面
def main():
root = Tk()
root.title('学生信息管理系统')
Center.show_center(root)
root.resizable(False, False)
# 图标
root.iconphoto(False, PhotoImage(file="../image/icon.png"))
# root.iconbitmap("../image/icon.png")
main_label = Label(root, text='学生信息管理系统', font=('Microsoft yahei', 24), height=5, fg='#484740')
main_label.place(relx=0.2, rely=-0.1, relwidth=0.6) # 布局,放置
add_btn = Button(root, text='添加学生信息', background='lightgreen', activebackground='lightgreen',
relief=GROOVE, command=lambda: [root.destroy(), add()])
add_btn.place(relx=0.3, rely=0.25, relheight=0.1, relwidth=0.4)
delete_btn = Button(root, text='删除学生信息', background='lightgreen', activebackground='lightgreen',
relief=GROOVE, command=lambda: [root.destroy(), delete()])
delete_btn.place(relx=0.3, rely=0.4, relheight=0.1, relwidth=0.4)
revise_btn = Button(root, text='修改学生信息', background='lightgreen', activebackground='lightgreen',
relief=GROOVE, command=lambda: [root.destroy(), revise()])
revise_btn.place(relx=0.3, rely=0.55, relheight=0.1, relwidth=0.4)
# 退出二次确认
def exit_if():
exit_result = askquestion(title='退出', message='是否退出?')
# print('askquestion: %s'.rjust(18) % exit_result) # 查看返回值
if exit_result == "yes":
root.destroy()
else:
pass
exit_btn = Button(root, text='退出', background='gray', activebackground='gray', relief=GROOVE,
command=exit_if)
exit_btn.place(relx=0.3, rely=0.7, relheight=0.1, relwidth=0.4)
# 绑定事件
def exit_bind(self):
exit_if()
# 绑定ESC键
root.bind("", exit_bind)
inquire_btn = Button(root, text='查询\n学生\n信息', background='lightblue', activebackground='lightblue',
relief=GROOVE, command=lambda: [root.destroy(), inquire()])
inquire_btn.place(relx=0.1, rely=0.25, relheight=0.5, relwidth=0.1)
all_btn = Button(root, text='显示\n所有\n学生\n信息', background='lightblue', activebackground='lightblue',
relief=GROOVE, command=lambda: [root.destroy(), show_all()])
all_btn.place(relx=0.8, rely=0.25, relheight=0.5, relwidth=0.1)
root.mainloop() # 显示窗口
# 登录界面
def login():
login_tk = Tk()
login_tk.title('登录')
Center.show_center(login_tk)
login_tk.resizable(False, False) # 不可调整大小和最大化
login_tk.iconphoto(False, PhotoImage(file="../image/icon.png"))
login_word = Label(login_tk, text='登 录', font=('Microsoft yahei', 28), height=5, fg='#5d5553')
login_word.place(relx=0.3, rely=-0.09, relwidth=0.4)
# 字样
no_label = Label(login_tk, text='账号')
name_label = Label(login_tk, text='密码')
no_label.place(relx=0.17, rely=0.3, relwidth=0.2, relheight=0.05)
name_label.place(relx=0.17, rely=0.47, relwidth=0.2, relheight=0.05)
username = StringVar()
password = StringVar()
# 输入框
username_input = ttk.Entry(login_tk, textvariable=username, font=('Microsoft yahei', 11))
password_input = ttk.Entry(login_tk, textvariable=password, font=('Microsoft yahei', 11), show='●') # 隐藏密码
username_input.place(relx=0.25, rely=0.35, relwidth=0.5, relheight=0.05)
password_input.place(relx=0.25, rely=0.52, relwidth=0.5, relheight=0.05)
# 判断
def user():
username_txt = username.get()
password_txt = password.get()
# print(username_txt)
# print(password_txt)
# 账号密码
if username_txt == USERNAME and password_txt == PASSWORD:
print('登录成功!')
# 登录成功进入主界面
login_tk.destroy()
main()
elif len(username_txt) == 0:
# print('请输入账号!')
showerror(title='提示', message='请输入账号!')
elif len(password_txt) == 0:
# print('请输入密码!')
showerror(title='提示', message='请输入密码!')
elif username_txt != USERNAME or password_txt != PASSWORD:
# print('登陆失败!')
showerror(title='提示', message='请输入正确的账号密码!')
else:
login_tk.quit()
login_btn = ttk.Button(login_tk, text='登 录', command=lambda: [user()])
login_btn.place(relx=0.4, rely=0.72, relwidth=0.2, relheight=0.07)
# 按钮事件
def btn_bind(self):
user()
# 绑定按钮
login_tk.bind("", btn_bind) # 绑定回车键
login_tk.mainloop()
if __name__ == '__main__':
login()
tool.py
USERNAME = 'admin' # 用户名
PASSWORD = '123456' # 密码
PATH = '../DB_stu/student.txt' # 文件路径
# 保存文件
class Save_txt:
@staticmethod
def save(self):
try:
stu_txt = open(PATH, 'a', encoding='utf-8')
except FileNotFoundError:
stu_txt = open(PATH, 'w+', encoding='utf-8')
for item in self:
stu_txt.write(str(item) + '\n') # 将内容写入文件中
# 窗口居中
class Center:
@staticmethod
def show_center(self_tk):
sw = self_tk.winfo_screenwidth()
sh = self_tk.winfo_screenheight()
ww = 600
wh = 500
x = (sw - ww) / 2
y = (sh - wh) / 2
self_tk.geometry("%dx%d+%d+%d" % (ww, wh, x, y))
图标:
data.txt
{'学号': '202007020028', '姓名': '王光明', '性别': '男', '年龄': 20, '学院': '经济学院', '专业': '电子商务'}
{'学号': '202100620002', '姓名': '李白', '性别': '男', '年龄': 19, '学院': '现代信息产业学院', '专业': '人工智能'}
{'学号': '202003220015', '姓名': '赵六娇', '性别': '女', '年龄': 21, '学院': '会计学院', '专业': '会计学'}
{'学号': '202205220033', '姓名': '李新春', '性别': '男', '年龄': 18, '学院': '外国语学院', '专业': '商务英语'}
{'学号': '202106120041', '姓名': '李建国', '性别': '男', '年龄': 20, '学院': '信息技术与工程学院', '专业': '物联网'}
{'学号': '202202010040', '姓名': '张光明', '性别': '男', '年龄': 19, '学院': '法学院', '专业': '法学'}
{'学号': '202007020025', '姓名': '王国保', '性别': '男', '年龄': 20, '学院': '经济学院', '专业': '经济学'}
{'学号': '202100620008', '姓名': '钟馗', '性别': '男', '年龄': 19, '学院': '现代信息产业学院', '专业': '智能讯飞'}
{'学号': '202003220019', '姓名': '欧阳帅', '性别': '男', '年龄': 21, '学院': '管理学院', '专业': '物流管理'}
{'学号': '202205220023', '姓名': '钟葵', '性别': '女', '年龄': 18, '学院': '外国语学院', '专业': '西班牙语'}
{'学号': '202107720055', '姓名': '程梨花', '性别': '女', '年龄': 20, '学院': '信息技术与工程学院', '专业': '软件工程'}
{'学号': '202207550065', '姓名': '黄国行', '性别': '男', '年龄': 19, '学院': '法学院', '专业': '法学'}
{'学号': '202000990044', '姓名': '欧扬风', '性别': '男', '年龄': 20, '学院': '经济学院', '专业': '经济学'}
{'学号': '202134650013', '姓名': '何家', '性别': '女', '年龄': 19, '学院': '艺术设计学院', '专业': '视觉传达'}
{'学号': '202000870036', '姓名': '赵福', '性别': '男', '年龄': 21, '学院': '会计学院', '专业': '会计学'}
{'学号': '202207880015', '姓名': '白柏林', '性别': '男', '年龄': 18, '学院': '外国语学院', '专业': '日语'}
{'学号': '202107720016', '姓名': '蔡家豪', '性别': '男', '年龄': 20, '学院': '信息技术与工程学院', '专业': '物联网'}
{'学号': '202207110027', '姓名': '严离离', '性别': '女', '年龄': 19, '学院': '法学院', '专业': '法学'}
{'学号': '202002080040', '姓名': '沈锅锅', '性别': '女', '年龄': 20, '学院': '经济学院', '专业': '经济学'}
{'学号': '202105110016', '姓名': '王安时', '性别': '男', '年龄': 19, '学院': '现代信息产业学院', '专业': '智能讯飞'}
{'学号': '202029420038', '姓名': '欧阳帅', '性别': '男', '年龄': 21, '学院': '管理学院', '专业': '酒店管理'}
{'学号': '202233300016', '姓名': '苏政', '性别': '男', '年龄': 18, '学院': '外国语学院', '专业': '德语'}
{'学号': '202209060028', '姓名': '吴茉莉', '性别': '女', '年龄': 19, '学院': '现代信息产业学院', '专业': '大数据'}
{'学号': '202000780015', '姓名': '常北北', '性别': '女', '年龄': 20, '学院': '经济学院', '专业': '金融学'}
{'学号': '202100640029', '姓名': '冯书节', '性别': '男', '年龄': 19, '学院': '现代信息产业学院', '专业': '计科华为'}
{'学号': '202000780027', '姓名': '欧明姚', '性别': '男', '年龄': 21, '学院': '会计学院', '专业': '审计学'}
{'学号': '202202280018', '姓名': '罗浩', '性别': '男', '年龄': 18, '学院': '外国语学院', '专业': '德语'}
{'学号': '202200550017', '姓名': '曹永达', '性别': '男', '年龄': 18, '学院': '国际学院', '专业': '市营双语创新'}
{'学号': '202244400016', '姓名': '段岚', '性别': '男', '年龄': 18, '学院': '外国语学院', '专业': '日语'}
{'学号': '202209010028', '姓名': '李璐', '性别': '女', '年龄': 19, '学院': '现代信息产业学院', '专业': '大数据'}
{'学号': '202000390015', '姓名': '武子韬', '性别': '男', '年龄': 20, '学院': '经济学院', '专业': '金融学'}
{'学号': '202100880029', '姓名': '龚杰宏', '性别': '男', '年龄': 19, '学院': '现代信息产业学院', '专业': '计科华为'}
{'学号': '202054670027', '姓名': '钟云熙', '性别': '女', '年龄': 21, '学院': '会计学院', '专业': '审计学'}
{'学号': '202245890018', '姓名': '蔡致远', '性别': '男', '年龄': 18, '学院': '外国语学院', '专业': '德语'}
{'学号': '202200660017', '姓名': '郑岚', '性别': '女', '年龄': 18, '学院': '国际学院', '专业': '市营双语创新'}
{'学号': '202202010013', '姓名': '小明', '性别': '男', '年龄': 20, '学院': '信息技术与工程学院', '专业': '软件工程'}
(资源已上传博客,同学们可进行下载)