Python学生信息管理系统_开发(GUI界面)
Posted 秋天中的一片叶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python学生信息管理系统_开发(GUI界面)相关的知识,希望对你有一定的参考价值。
学生信息管理系统的开发
模块: 1. 系统登录界面 --> logingui.py
2. 系统主界面 --> maingui.py
3. 学生明细界面 --> detailgui.py
4. 修改登录账号密码界面 --> changepassword.py
5. GUI界面需要的图库
6. 数据 --> (1) 登录账号相关文件 (loginuser_info.txt) (2) 加载到主界面中显示的学生信息文件(student_info.txt)
# 图片部分
===》 注意: 这里的图片全部是png格式的 代码中窗体小图标是ico格式的可以通过网上转换图片生成ico格式的图片
# 文件部分
student_info.txt
95001,橘右京,20,男,15977693796,juyoujing@yahoo.cn.jp,日本大阪府大阪市,1988/9/12,110103199110186521,2010年6月18日,战士,橘子成精,18911213348 95002,韩信,19,男,18695719656,www.hanxin163.com,陕西省西安市韩台镇韩家村196号,1990/5/30,610103199110182714,2010年2月18日,刺客,韩悠悠,15977693321 95003,亚瑟,30,男,15834769921,yase@chengxin196.com,美国卡里福尼亚州,1981/7/21,370626798909071691,1978年7月17日,战士,亚历山大三世,18955789581 95004,王昭君,18,女,18977623571,wangzhaojun@qq.com,江苏省苏州市姑苏区,1998/12/3,320506198911112836,2014年9月30日,法师,王他爹,17966289971 95005,阿珂,17,女,13644893365,jingke@qq.com,山东省烟台市芝罘区,2000/3/23,370602198909071333,1999年9月9日,刺客,阿可可,15855372291 95006,白起,28,男,15962789930,www.baiqi@163.com,陕西省西安市,1978/12/31,610103199110182255,1978年12月30日,战士,白斩,18633462237 95007,苏烈,37,男,18912347689,sulie@yahoo.cn.jp,辽宁省黑龙江市,1975/9/30,3205061989167810056,1971年8月12日,战士,苏醒,15977889900 95008,虞姬,18,女,15942887540,www.yuji_s@qq.com,江苏省苏州市,1999/6/10,320506198911110056,1998年2月28日,射手,虞阵子,15890017789 95009,鲁班,16,男,18856713396,luban250@163.com,河南省郑州市,2001/5/7,3865198911110011,2001年12月12日,射手,鲁班大师,15977889911 95010,狄仁杰,20,男,18867321541,direnjie@alibaba.com,江苏省杭州市,1996/10/30,32050619891230056,1998年2月1日,射手,狄小兵,15778890071 95011,东方曜,21,男,15855667913,dongfangyao@qq.com,陕西省西安市,1997/10/24,610103199110181412,2008年11月06日,战士,东方朔,18977239971 95012,嬴政,29,男,15588988888,yingzheng@beifeng.com,陕西省西安市,1981/4/12,610103199110182079,1999年5月31日,法师,嬴政他爹,18857613374 95013,蔡文姬,20,女,18666890013,caicai@alibaba.com,云南省大理市,1997/10/16,320506156911110056,1998年11月27日,辅助,蔡铭,18758092231 95014,甄姬,24,女,18562782278,www.zhenji@163.com,山西省大同市,1994/12/1,320506198911110056,1997年4月30日,法师,甄子丹,16599002345 95015,宫本武藏,27,男,18977889900,juyoujing@yahoo.cn.jp,日本大阪府大阪市,1982/3/19,3205061989112346,1982年2月21日,战士,宫本重生,17971889920 95016,明世隐,30,男,18662722447,www.mingshiyin@163.com,湖南省荆州市,1977/11/11,320506198911110216,1971年2月28日,辅助,明世隐公子,15888990011 95017,李元芳,17,男,15727458228,liyuanfang@ibm.com,湖北省武汉市,1999/12/11,32050619891111112234,2004年7月8日,射手,李元直,1857789012237 95018,盾山,37,男,18677882288,www.dunshan@qq.com,山东省烟台市,1975/12/12,370602198909071472,1978年5月17日,辅助,盾地,15888887777 95019,诸葛亮,24,男,18911118888,zhugeliang@qq.com,湖南省荆州市,1996/6/8,320506198911223344,1998年9月11日,法师,诸葛苏,15777812910 95020,赵云,27,男,18889966657,zhaozilong@qq.com,河南省荆州市,1993/12/12,320506198922331005,1989年10月28日,战士,赵形,167877889109 95021,关羽,29,男,18811007788,guanyu@yahoo.com,山东省烟台市,1981/12/14,370602198909070437,1990年1月12日,战士,关包,13877639961 95022,不知火舞,18,女,18677120091,huwu@yahoo.co.jp,日本东京,1997/2/14,370602199702141471,2020年4月1日,法师,安迪,18612416097 95023,张飞,28,男,15811221190,zhangfei@qq.com,河南省郑州市,1985/1/30,320506198501301014,2020年1月1日,坦克,刘备,15988002581
loginuser_info.txt
liupeng,P@ssw0rd,1 admin,123.com,0 zhangsan,123.com,0
一,系统登录界面
思路: 1. GUI界面的设计 --> 通过python自带的 tkinter 及 tkinter的加强版 tkinter.ttk 来实现登录界面的部署 (编码部署界面 --> 原因:为了日后习惯web开发)
2. GUI界面下通过用户名密码进行身份验证 --> 读取到文件中的用户信息存入集合 --> 集合中通过元素[0][1][2]的方式管理学生信息的用户名,密码及锁定状态
3. 用户登录判定: (1) 判断登录用户是否被锁定
(2) 判断登录用户是否存在
(3) 判断登录用户密码输入是否正确
(4) 判断登录用户密码登录是否超过3次,3次判定为锁定并写入到文件
代码实现:
from tkinter import * import tkinter.ttk as ttk import os from tkinter.messagebox import * from datetime import datetime import wangzhexiagu.GUI_student_system.maingui as man class Login_Windows(Tk): def __init__(self): """ 主构造函数 1. 初始化登录界面窗体 2. 布局登录窗体并配置各个按键的属性 3. 实现用户验证功能 """ super().__init__() #初始化框口 self.title("登录界面") self.geometry("640x420+300+200") #通过控制图像大小可以通过+号来调整窗体出现的位置 self.resizable(0,0) #固定窗体大小.不允许改动窗体大小. resizable(0,0)表示x轴为0y轴也为0 self.iconbitmap(R"C:\\Users\\Administrator\\PycharmProjects\\untitled1\\wangzhexiagu\\GUI_student_system\\photo\\china.ico") #添加图片背景色 self["bg"] = "RoyalBlue" #传统tkinter中配置颜色方法 #加载窗体 self.SetUp_UI() #设置全局变量 self.file_path = R"C:\\Users\\Administrator\\PycharmProjects\\untitled1\\wangzhexiagu\\GUI_student_system\\loginUserInfo_Data\\loginuser_info.txt" self.user_list = [] #用户存储读取文件中所有的元素 self.misspasswd_counter = 0 #记录password错误的次数 self.input_user = "" #记录当前用户 self.input_password = "" #记录当前用户密码 self.current_login_list = [] #存储登录的账号和密码 #自动执行文件中文件的加载 self.load_localfile_info() #showinfo(message=self.user_list) #通过该提示可以直接看文件是否被读取成功! #设置GUI页面窗体及控件的布局 def SetUp_UI(self): #通过style设置属性 self.Style01 = ttk.Style() self.Style01.configure("TLabel",font=("微软眼黑",18,"bold"),background = "RoyalBlue",foreground = "white") self.Style01.configure("TButton", font=("微软眼黑", 11), background="RoyalBlue", foreground="black") #加载窗体图片 self.login_img = PhotoImage(file =R"C:\\Users\\Administrator\\PycharmProjects\\untitled1\\wangzhexiagu\\GUI_student_system\\photo\\school_demo.png") self.label_img = ttk.Label(self,image = self.login_img) self.label_img.pack(padx = 10,pady = 10) #创建Label + Entry ----用户名 self.username = ttk.Label(self,text = "用户名") self.var_user = StringVar() #为了获取键盘输入 self.username.pack(side = LEFT,padx = 10, pady = 10) self.user_entry = ttk.Entry(self,width = 15,textvariable =self.var_user,font=("微软眼黑",13,"bold"))# bold代表字体粗体 self.user_entry.pack(side = LEFT,padx = 10, pady = 10) #创建Label + Entry ----密码 self.password = ttk.Label(self,text = "密码") self.var_password = StringVar()#为了获取键盘输入 self.password.pack(side = LEFT,padx = 10, pady = 10) self.password_entry = ttk.Entry(self,show = "*",width = 15,textvariable=self.var_password,font=("微软眼黑",13,"bold")) #show方法代表密码密文 self.password_entry.pack(side = LEFT,padx = 10, pady = 10) #创建Button ---- 登录 self.button_login = ttk.Button(self,text = "登录",command = self.login) self.button_login.pack(side = LEFT,padx = 10, pady = 10) def load_localfile_info(self): """ 加载本地文件: 通过readline()方法一次读取一行的方式进行读取(避免日后文件过大一次性读取的弊端) :return: """ if not os.path.exists(self.file_path): showinfo("系统提示","文件不存在.请确认后重新加载!!") else: try: with open(self.file_path,mode = "r") as fd: current_list = fd.readline() #一次读一行 while current_list: #表示直到current_list中所有元素被读完,循环结束 temp_list = current_list.split(",") #按照逗号把每个list中的元素分割出来 self.user_list.append(temp_list) #把分割后的每个元素重新添加到user_list列表中 current_list = fd.readline() #因为我们一次只读一行。读完后如果不加这一句那么循环会一直只读第一行。 except: showinfo("系统信息","文件读取出现异常.请联系管理员!!") def login(self): """ 用户身份验证功能的实现 1. 获取到文件中的用户名,密码,状态(是否被锁定) 2. 判断用户是否被锁定及是否是规定用户以外的非法用户登录(如果是拒绝登录) 3. 用户正确判断密码是否匹配,密码不匹配3次被锁定并写入到文件 :return: """ # 获取输入的用户名及密码 self.input_user = self.var_user.get() self.input_password = self.var_password.get() #showinfo("提示信息","用户名:" + input_user + "\\n" + "密码:" + input_password) #实现身份验证 for index in range(len(self.user_list)): #这里的user_list 为之前从文件中读取重新存入list列表中的数据 #先判断用户名是否存在 if self.input_user.strip().lower() == str(self.user_list[index][0]).strip().lower(): #如果用户名存在,再判断用户名是否被锁定。1为锁定,0为active. if "1" in str(self.user_list[index][2]): showinfo("系统提示", "该用户被锁定.请联系管理员解锁后再登录。") break else: #如果用户存在并且是active的状态再判断密码是否正确 if self.input_password != str(self.user_list[index][1]): self.misspasswd_counter +=1 #初始值设置为0.如果上述条件不成立则循环加1次 if self.misspasswd_counter >=3: #设置密码错误次数最大不能超过3次 showinfo("系统提示","密码输入错误3次账号被锁定!") #改变锁定账户的状态(如果错误3次则改变文件中账户的状态把第3个元素变为1代表用户被锁定) self.user_list[index][2] = "1\\n" #这里需要加一个空格 #写入文件 self.write_file() #调用下列write_file()方法 else: showinfo("系统提示", "密码错误,请重新输入") break else: self.misspasswd_counter = 0 #如果输入的password正确那么这里的错误次数还是为0 self.current_login_list = self.user_list[index] #用户密码输入都正确则加载主窗体() self.upload_main() break #这句话的意思是:循环到最后如果没有找到相同的用户名则用户判定为不存在!!!(这句话为重点,也是因为这句话才循环时用索引) if index == len(self.user_list)-1: showinfo("系统提示","输入的用户名不存在!") def write_file(self): """ 写入文件":1.分2次写入第一次先清空原文件,第2次再逐一写入 2. 写入的是用户登录后反应的最新的状态信息 :return: """ try: #[1] 先清空原文件(不放心可以先备份原文件再执行代码,不然数据会丢失) with open(self.file_path,mode="w") as fd: fd.write("") #不写任何东西代表清空 #[2] 再逐一把user_list中的数据写入到文件."a"代表追加写入 with open(self.file_path,mode = "a") as fd: for item in self.user_list: fd.write(",".join(item)) #通过.join()方法指定写入时按照什么进行分割写入文件。这里指定的是按照逗号分割写入 except: showinfo("系统信息","写入数据失败.") def upload_main(self): """ 加载主窗体函数: 1. 用户验证通过后自动关闭当前窗体 2. 用户验证通过后自动加载主窗体 :return: """ #关闭当前窗体 self.destroy() #加载主窗体 self.main_window = man.Main_Windows(self.current_login_list,self.get_login_time()) #man.Main_Windows()中self.current_login_list及self.get_login_time()为加载登录主窗体后实现当前用户及登录时间显示的功能 def get_login_time(self): """ 实现用户登录后自动加载登录时间功能 #通过import datetime这个模块中datetime.today()方法来实现.当然也可以通过其他方法实现比如时间元祖等 :return: """ today = datetime.today() return ("%04d/%02d/%02d %02d:%02d:%02d" % ( today.year, today.month, today.day, today.hour, today.minute, today.second)) if __name__ == "__main__": this_login = Login_Windows() this_login.mainloop()
二,系统主界面
思路: 1. GUI界面的设计 --> 同上同样是通过tkinter进行设计
(1) 上部 : 加载主窗体的图片 * 右下方显示当前登录的用户及当时登录时的系统时间 (这里是这部分的重点)
(2) 左部: 左边部分是功能区域 (用户的增删改及修改用户及密码的GUI界面部署)
(3) 右部: 右边部分分2大区域 1. 查询区域( 学号,姓名,年龄,手机号码,住址 等 来查询的GUI界面部署)
2. 数据展示区域(展示的是添加进来的student_info.txt中的数据,及查询后所展示的数据)
3. 查询区域中查询按钮及显示全部数据的GUI部署
(4) 总体 : 数据最终保存及退出界面的GUI界面部署
2. 上部: 如何显示当前用户及当前登录的系统时间
(1) logingui界面中的login方法里,用户最终登录系统成功的节点下 --> 获取登录成功的用户名及密码 (这里主要用到的是用户名) --> 存入到集合备用
(2) logingui界面中,创建get_login_time()方法获取当前的系统时间
(3) maingui主界面的构造函数中传参并实例化,把login界面中的集合在主界面下进行使用
(4) 主界面上部右下方的label窗口中,加载当前的用户和时间
3. 左部及右部 : 查看, 添加,修改 调用的都是同一个GUI界面. 如何实现在加载相同的窗口时,提示标题不相同
(1) 通过flag来标识登录的detailgui是查看还是添加,修改 --> flag为全局变量 --> GUI窗体设计title部分不要写死 --> 通过获取title状态的方式识别
(2) 创建load_window_flag方法来控制每种状态下窗口的显示
1. flag =1 代表查看窗口 --> 查看窗口不允许更改任何信息,因此禁用detailgui查看窗口下的所有控件
2. flag = 2 代表添加窗口 --> 因为是添加所以不做任何限制
3. flag = 3 代表修改窗口 --> 学号绑定不许修改其他控件允许修改 -->可以更加优化修改窗口中每个控件的值的输入(因为时间原因我本人没有做更好的优化)
(3) 添加,修改,删除,修改密码等具体功能的实现 --> 详情见代码有注释
4. 右部: TreeView控件中展示所有学员信息 -->通过查询功能的实现来展示 --> 详情见代码
代码实现:
from tkinter import * import tkinter.ttk as ttk import os from tkinter.messagebox import * import wangzhexiagu.GUI_student_system.detailgui as dt import wangzhexiagu.GUI_student_system.change_password as ps class Main_Windows(Tk): """ 主窗体的构造函数 1. current_user,current_time的引入是为了加载logingui.py窗体中用户输入及加载登录时间记录时间的参数 2. 同样设计主窗体下界面的布局及配置 """ def __init__(self,current_login_user,current_time): #current_login_user为了实现登录信息的加载(记录logingui界面中当前用户是谁) #current_time同样是为了记录当前用户登录的系统时间 super().__init__() self.title("主窗体") self.geometry("1200x700+1+20") # 通过控制图像大小可以通过+号来调整窗体出现的位置 self.resizable(0, 0) # 固定窗体大小.不允许改动窗体大小. resizable(0,0)表示x轴为0y轴也为0 self.iconbitmap(R"C:\\Users\\Administrator\\PycharmProjects\\untitled1\\wangzhexiagu\\GUI_student_system\\photo\\china.ico") # 加载.ico文件到窗口小图标. 网上可以将png转成ico文件 # 添加图片背景色 self["bg"] = "RoyalBlue" #设置全局变量 self.login_times = current_time #为了记录用户的登录时间 self.all_list = [] # 读取student_info.txt中所有的元素并存入all_list中 self.current_stu_list = [] #存储双击行匹配到的最终数据 self.get_number_result = [] #用户存储获取到的所有学员信息 self.file_path = R"C:\\Users\\Administrator\\PycharmProjects\\untitled1\\wangzhexiagu\\GUI_student_system\\loginUserInfo_Data\\student_info.txt" self.action_flag = 0 #设置查看/修改/添加学生信息的title值,默认为0 self.current_user_list = current_login_user #把login界面的list传到主界面接收 #加载窗体 self.Setup_UI() #自动执行函数 self.Load_local_Data() # 自动加载数据(加载的是all_list中已经读取到的所有数据) self.load_TreeView(self.all_list) #自动将all_list中每一行的数据加载到TreeView中展示 #将窗体的行为转化为方法 self.protocol("WM_DELETE_WINDOW",self.close_windows) #"WM_DELETE_WINDOW"为固定写法 def Setup_UI(self): """ 布局主窗体的窗体并对其中的控件属性进行配置 :return: """ #设置Sytle配置控件的属性 self.Style01 = ttk.Style() self.Style01.configure("left.TPanedwindow",background="RoyalBlue") self.Style01.configure("right.TPanedwindow", background="skyblue") self.Style01.configure("TButton",font = ("微软雅黑",12,"bold")) self.Style01.configure("TLabel", font=("微软雅黑", 10, "bold")) self.Style01.configure("labframe.TButton", font=("微软雅黑", 10, "bold")) self.Style01.configure("title1.TLabel", font=("微软雅黑", 10, "bold"),background = "lightblue") # 加载窗体图片 self.login_img = PhotoImage(file=R"C:\\Users\\Administrator\\PycharmProjects\\untitled1\\wangzhexiagu\\GUI_student_system\\photo\\1.png") self.label_img = ttk.Label(self, image=self.login_img) self.label_img.pack() #加载当前用户和时间 self.label_login_user = ttk.Label(self,text = "当前登录用户:" + str(self.current_user_list[0]).title() + "\\n登录时间:" + self.login_times,style = "title1.TLabel" ) #str(self.current_user_list[0]).title()为用户登录后的首字母显示未大写 self.label_login_user.place(x=1000,y=165) # 左边按钮区域的布局 self.pan_left = ttk.PanedWindow(width =200,height=500,style ="left.TPanedwindow" ) self.pan_left.pack(side = LEFT,padx=3,pady=1) # 添加左边区域按钮 self.buttion_useradd = ttk.Button(self.pan_left,text = "添加学生",width =12,command = self.add_student) self.buttion_useradd.place(x = 30,y = 20) self.buttion_userupdate = ttk.Button(self.pan_left,text = "修改学生",width =12,command = self.update_student) self.buttion_userupdate.place(x = 30,y = 60) self.buttion_userdelete = ttk.Button(self.pan_left,text = "删除学生",width =12,command = self.delete_student) self.buttion_userdelete.place(x = 30,y = 100) self.buttion_changepassword = ttk.Button(self.pan_left,text = "更改密码",width =12,command = self.change_password_windows) self.buttion_changepassword.place(x = 30,y = 140) #右边按钮区域的布局 self.pan_right = ttk.PanedWindow(width = 991,height = 500,style = "right.TPanedwindow" ) self.pan_right.pack(side = LEFT) # 添加查询区域(属于右边区域) self.labelFrame_query = ttk.LabelFrame(self.pan_right,text = "学生信息",width =990,height = 60) self.labelFrame_query.place(x=1,y=1) #添加控件 self.label_number = ttk.Label(self.labelFrame_query,text = "学号:") self.label_stu_no = StringVar() self.label_number.place(x =10,y =10) self.entry_number = ttk.Entry(self.labelFrame_query,textvariable = self.label_stu_no,font = ("微软雅黑",10,"bold"),width=8) self.entry_number.place(x =50,y =10) self.label_name = ttk.Label(self.labelFrame_query,text = "姓名:") self.get_stu_name = StringVar() self.label_stu_name = StringVar() self.label_name.place(x =130,y =10) self.entry_name = ttk.Entry(self.labelFrame_query,textvariable = self.get_stu_name,font = (Java学习笔记8.2.2 JDBC实战 - GUI学生信息管理系统Java学习笔记8.2.2 JDBC实战 - GUI学生信息管理系统