目录
6.2#这个是Click_function,和上面这个代码它两个是不同py哦
一、课题开发环境
1..使用IJ软件,配置Python 3.9.2解释器,基于python语言
2.使用Navicat premium 15数据库管理和mysql-5.5.54-winx64.ms服务
二、课题研究的主要功能目标
1.采用交互工作方式、可连续操作,登录界面显示当前日期和时间
2.建立数据库文件,与数据库连接,进行读取存入数据库
3..可以进行增删改查保存文件操作
4.按学号、姓名、专业、班级查找
三、课题所用本课程相关知识点如下
1.在本课题设计采用存储密度大且能实现随机存取的顺序存储结构
2.运用了条件语句、循环、数组、函数操作,利用流程图表示算法
3.基于线性表顺序查找(按位查找),算法分析的方法,包括时间复杂度,空间复杂度和算法可优化程度
四、设计主要思路
1.创建一个登录界面,显示当前日期和时间。再创建一个主窗口 ,包括宿舍查新系统的标题,“添加学生”、“删除学生”、“修改学生信息”、“保存文件”、”退出系统“功能。
2.添加学生功能:点击“添加学生“菜单选项,弹出一个新窗口,包括姓名、学号、性别等学生基本信息。用户填写完毕后,点击”确认“按钮,将新学生信息保存到MySQL数据库中。
3.删除学生功能:选中要删除的学生,点击”删除学生“按钮,既可以删除,并与Mysql数据库里学生信息表同步更新
4.修改学生信息功能:选中要修改的学生,然后点击”修改学生信息”菜单选项,弹出一个新窗口,包括姓名、学号、性别等学生基本信息,用户修改完后点击确认将修改后的学生信息保存到数据库中,数据库里的学生信息表同步更新。
5.查询学生信息功能:可以按学号、姓名、专业、班级进行二分法查找
6.“退出系统”功能:既可退出宿舍信息管理界面
五、运行效果图
1、实现窗口图形化登录,可连续操作,运行效果如下图
2、显示全部功能(把所有学生信息显示出来,运行效果如下图
3、按学号查找(根据学号查找出学生信息),运行效果如下图
4、按姓名查找(根据姓名查找出学生信息),运行效果如下图
5、按专业查找(根据专业查找出学生信息),运行效果如下图
6、按班级查找(根据班级查找出学生信息),运行效果如下图
7、学号、姓名、专业、班级,两两组合或多个组合查找,运行效果如下图
8、新增学生信息功能(向后台mysql数据库插入一条学生信息),运行效果如下图
9、修改学生信息功能(修改某位学生信息),运行效果如下图
10、删除学生信息、保存文件、退出系统等功能在这里我就不一一进行演示了哦,友友们可以复制我的源代码在自己电脑上跑一跑
六、源代码分享
6.1#这个是main code
import tkinter as tk from tkinter import ttk from tkinter import messagebox,HORIZONTAL,VERTICAL from tkinter.messagebox import showinfo, askyesno from tkinter.ttk import Style, PanedWindow, Button, LabelFrame, Treeview import pandas as pd from sqlalchemy import create_engine from PIL import Image, ImageTk from tkinter import Frame import time import Click_function host='localhost' user='root' password='root123' database='information' port="3306" charset="utf8" conn_str = f"mysql+pymysql://{user}:{password}@{host}:{port}/{database}?charset={charset}" engine = create_engine(conn_str) user_name = "admin" password = "123456" class Root: # 这是第一个页面 def __init__(self, window): #构造器方法 self.window = window #owner是实例属性 self.window.title("欢迎登录后台校园宿舍管理界面平台") self.window.geometry("1000x617") self.window.resizable(0,0) self.frame = Frame(self.window) self.frame.config(bg="#FFFFFF") self.frame.pack() self.img_lable() self.lable() self.clock() self.login() def lable(self): tk.Label(self.frame,text="校园宿舍管理系统", font=("华文行楷", 25),bg="#FFFFFF").place(relx=0.52, rely=0.2, anchor='center') tk.Label(self.frame, text="2024年2月26日-2024年3月7日 @来自晨曦", font=("方正舒体", 13),bg="#FFFFFF").place(relx=0.44, rely=0.93, relheight=0.04, relwidth=0.32,anchor='center') def img_lable(self): img = Image.open("scenery.png") img = img.resize((1000, 617)) # 规定图片大小 photo = ImageTk.PhotoImage(img) # 使用神器PIL库可以设置照片大小并且可以支持jpg格式等 label = tk.Label(self.frame, image=photo, borderwidth=0) label.img = photo # to keep the reference for the image.不保存会显示空白 label.grid(row=0, column=0) def login(self): # 将俩个标签分别布置在第一行、第二行 tk.Label(self.frame, text="用户名:", font=("宋体", 15),bg="#FFFFFF").place(relx=0.4, rely=0.35, anchor='center') tk.Label(self.frame, text="密码:", font=("宋体", 15),bg="#FFFFFF").place(relx=0.4, rely=0.48, anchor='center') # 创建输入框控件 self.e1 = tk.Entry(self.frame) # 以 * 的形式显示密码 self.e2 = tk.Entry(self.frame, show='*') self.e1.place(relx=0.46, rely=0.33, relheight=0.04, relwidth=0.18) self.e2.place(relx=0.46, rely=0.46, relheight=0.04, relwidth=0.18) tk.Button(self.frame, text="登录", width=20,bg="#FFFFFF",command=self.check).place(relx=0.35, rely=0.62, anchor='center') tk.Button(self.frame, text="退出", width=20,bg="#FFFFFF", command=self.window.quit).place(relx=0.65, rely=0.62, anchor='center') def check(self): if self.e1.get() == user_name and self.e2.get() == password: messagebox.showinfo(title="登录成功", message=f"欢迎登入管理界面") self.frame.destroy() Home(self.window) return True else: messagebox.showwarning(title="登录失败", message="账号或密码错误") self.e2.delete(0, tk.END) return False def clock(self): # 获取时间的函数 def gettime(): # 获取当前时间 dstr.set(time.strftime("%Y-%m-%d %H:%M:%S")) # 每隔 1s 调用一次 gettime()函数来获取时间 self.frame.after(1000, gettime) # 生成动态字符串 dstr = tk.StringVar() # 利用 textvariable 来实现文本变化 tk.Label(self.frame, textvariable=dstr, font=("方正舒体", 13),bg="#FFFFFF").place(relx=0.685, rely=0.93, relheight=0.04, relwidth=0.17,anchor='center') gettime() action_flag=1 def Scrollbar(Frame2, orient, command): pass class Home(): def __init__(self, window): self.window = window self.window.title(f"当前管理员为{user_name}") self.setup_UI() self.readExcel() self.query_result_list = [] self.flag = action_flag self.update=0 self.window.protocol("WM_DELETE_WINDOW", self.close_window) def readExcel(self): # 执行sql操作 sql="select * from college" self.head=pd.read_sql(sql,con=engine).columns.tolist() df = pd.read_sql(sql,con=engine) self.all_student_list = df.values.tolist() #把每一行存入一个列表再把每个列表存入列表 def del_Entry_content(self): self.Entry_sno.delete(0, tk.END) self.Entry_name.delete(0, tk.END) self.Entry_profess.delete(0, tk.END) self.Entry_class.delete(0, tk.END) def show_all(self): self.clear_Tree() # 把所有条件文本框清空 self.Entry_sno.delete(0, tk.END) self.Entry_name.delete(0, tk.END) self.Entry_profess.delete(0, tk.END) self.Entry_class.delete(0, tk.END) self.load_treeview(self.all_student_list) def load_treeview(self,current_list): for index in range(len(current_list)): self.Tree.insert("", index, values=(current_list[index][0], current_list[index][1], current_list[index][2], current_list[index][3], current_list[index][4], current_list[index][5], current_list[index][6])) def get_query_result(self): query_condition = [] query_condition.append(self.Entry_sno.get().strip()) # 采集学号信息 query_condition.append(self.Entry_name.get().strip()) # 采集姓名信息 query_condition.append(self.Entry_profess.get().strip()) query_condition.append(self.Entry_class.get().strip()) # 遍历List获取符合条件的学生信息 for item in self.all_student_list: if query_condition[0] in item[0] and query_condition[1] in item[1] and \ query_condition[2] in item[3] and query_condition[3] in item[4]: # 满足条件的学生 self.query_result_list.append(item) # 把结果加载的TreeView中 self.clear_Tree() self.load_treeview(self.query_result_list) self.query_result_list.clear() def clear_Tree(self): for i in self.Tree.get_children(): self.Tree.delete(i) def setup_UI(self): # 设定Style self.Style01 = Style() self.Style01.configure("TPanedwindow",bg="#dea32c") self.Style01.configure("TButton", width=10, font=("隶书", 15,)) # 上边:labe self.Pane_top = PanedWindow(self.window,width=900, height=85).place(x=5, y=5) tk.Label(self.Pane_top, text="欢迎来到宿舍信息管理界面", font=("方正舒体", 30),width=30).place(x=165, y=20) # 左边:按钮区域,创建一个容器 self.Pane_left = PanedWindow(self.window,width=100, height=500, style="TPanedwindow").place(x=5, y=100) # 这种写法下方是使用绝对距离 self.Pane_right = PanedWindow(self.window,width=800, height=500, style="TPanedwindow") self.Pane_right.place(x=210, y=100) # 这种写法下方是相对距离,明明写法含义都一样,结果却不一样简直莫名其妙。。。不是frame的原因,因为你把它挪上去在结尾添加下方frame位置会改变 # 添加左边按钮 self.Button_add = Button(self.Pane_left, text="新增学生信息",width=12,style="TButton",command=self.add_student).place(x=50, y=120) self.Button_update = Button(self.Pane_left, text="修改学生信息",width=12, style="TButton",command=self.update_student).place(x=50, y=200) self.Button_delete = Button(self.Pane_left, text="删除学生信息", width=12,style="TButton",command=self.delete_student).place(x=50, y=280) self.Button_modify = Button(self.Pane_left, text="保存文件", style="TButton",command=self.save_excel).place(x=50, y=360) self.Button_modify = Button(self.Pane_left, text="退出系统", style="TButton",command=self.close_window).place(x=50, y=440) # 添加右边按钮 # LabelFrame self.LabelFrame_query = LabelFrame(self.Pane_right, width=790, height=60) self.LabelFrame_query.place(x=5, y=5) # 添加控件 y1 = 1 y2 = -2 self.Label_sno = tk.Label(self.LabelFrame_query, text="学号:") self.Label_sno.place(x=5, y=y1) self.Entry_sno = tk.Entry(self.LabelFrame_query, width=12) self.Entry_sno.place(x=40, y=y2) self.Label_name = tk.Label(self.LabelFrame_query, text="姓名:") self.Label_name.place(x=125, y=y1) self.Entry_name = tk.Entry(self.LabelFrame_query, width=12) self.Entry_name.place(x=160, y=y2) self.Label_profess = tk.Label(self.LabelFrame_query, text="专业:") self.Label_profess.place(x=245, y=y1) self.Entry_profess = tk.Entry(self.LabelFrame_query, width=14) self.Entry_profess.place(x=280, y=y2) self.Label_class = tk.Label(self.LabelFrame_query, text="班级:") self.Label_class.place(x=380, y=y1) self.Entry_class = tk.Entry(self.LabelFrame_query, width=14) self.Entry_class.place(x=415, y=y2) self.Button_query = tk.Button(self.LabelFrame_query, text="查找", width=4,command=self.get_query_result) self.Button_query.place(x=525, y=y1 - 9) self.Button_all = tk.Button(self.LabelFrame_query, text="清空全部", width=8, command=self.clear_Tree) self.Button_all.place(x=600, y=y2 - 8) self.Button_all = tk.Button(self.LabelFrame_query, text="显示全部", width=8,command=self.show_all) self.Button_all.place(x=695, y=y2 - 8) # 添加TreeView控件 self.Tree =Treeview(self.Pane_right, columns=("学号", "姓名", "性别", "专业", "班级", "宿舍号", "手机号"), show="headings",height=25, selectmode='browse') scrollbar = ttk.Scrollbar(root, orient="vertical", command=self.Tree.yview) self.Tree.configure(yscrollcommand=scrollbar.set) scrollbar.pack(side="right",fill="y") # 设置每一个列的宽度和对齐的方式 self.Tree.column("学号", width=120, anchor="center") self.Tree.column("姓名", width=80, anchor="center") self.Tree.column("性别", width=70, anchor="center") self.Tree.column("专业", width=150, anchor="center") self.Tree.column("班级", width=140, anchor="center") self.Tree.column("宿舍号", width=100, anchor="center") self.Tree.column("手机号", width=100, anchor="center") # 设置每个列的标题 self.Tree.heading("学号", text="学号") self.Tree.heading("姓名", text="姓名") self.Tree.heading("性别", text="性别") self.Tree.heading("专业", text="专业") self.Tree.heading("班级", text="班级") self.Tree.heading("宿舍号", text="宿舍号") self.Tree.heading("手机号", text="手机号") self.Tree.place(x=5, y=50) def show_window(self): self.detail_window = Click_function.DetailWindow() def add_student(self): self.show_window() self.detail_window.show_save(self.all_student_list) self.window.wait_window(self.detail_window)#等待窗口被销毁 if self.detail_window.userinfo == 1: self.show_all() self.update=1 else: return def view_student(self,event):#此处event不可省略,删除后果自负 # 获取Tree表格双击某一行的数据,selection()如果没有指定参数,则表明以列表形式返回所有的item item = self.Tree.selection()[0] # 获取双击某一行的项目标识符 #一行数据所组成的列表 current_student_list = self.Tree.item(item, "values") self.show_window() self.detail_window.load_student_detail(current_student_list,1,-1) def update_student(self): try: item = self.Tree.selection()[0] # 获取双击某一行的项目标识符 except: showinfo("系统消息", "请选择要修改的学生") return # 一行数据所组成的列表 current_student_list = self.Tree.item(item, "values") # 遍历获得完整学生明细信息 index=self.all_student_list.index(list(current_student_list)) self.show_window() self.detail_window.tube(self.all_student_list) self.detail_window.load_student_detail(current_student_list,2,index) self.window.wait_window(self.detail_window)#等待窗口被销毁 if self.detail_window.userinfo == 1: self.show_all() self.update=1 else: return def delete_student(self): try: item = self.Tree.selection()[0] # 获取双击某一行的项目标识符 except: showinfo("系统消息", "请选择要删除的学生") return # 一行数据所组成的列表 current_student_list = self.Tree.item(item, "values") # 遍历获得完整学生明细信息 index=self.all_student_list.index(list(current_student_list)) # 询问是否删除 choose = askyesno("删除确认", "确定要删除该学生【学号:" + current_student_list[0] + ",姓名:" + current_student_list[3] + "】的信息吗?") if choose: # 执行删除动作 del self.all_student_list[index] self.show_all() showinfo("系统消息", "删除成功!") self.update=1 else: return def save_excel(self): if (self.update == 0): showinfo("系统消息", "当前文件未作修改,无需保存") return try: dic = {} for i in range(0, len(self.head)): lst = [] for student in self.all_student_list: lst.append(student[i]) dic[self.head[i]] = lst df = pd.DataFrame(dic) df.to_sql("information", con=engine, if_exists='replace') # 提醒 showinfo("系统消息", "保存成功") self.update=0 except: showinfo("系统消息", "写入文件出现异常") def close_window(self): if(self.update==0): self.window.destroy() return # 给用户提示:是否要保存数据 choose = askyesno("关闭前提醒", "关闭窗体前是否要将修改写入文件") if choose: try: dic = {} for i in range(0, len(self.head)): lst = [] for student in self.all_student_list: lst.append(student[i]) dic[self.head[i]] = lst df = pd.DataFrame(dic) df.to_sql("information", con=engine, if_exists='replace') # 提醒 showinfo("系统消息", "所有的修改已经写入到文件") # 关闭 self.window.destroy() except: showinfo("系统消息", "写入文件出现异常") else: self.window.destroy() if __name__ == '__main__': root = tk.Tk() Root(root) root.mainloop()
6.2#这个是Click_function,和上面这个代码它两个是不同py哦
from tkinter import * from tkinter.messagebox import showinfo from tkinter.ttk import * class DetailWindow(Toplevel): def __init__(self): super().__init__() self.config(bg="white") self.title("学生基本信息") self.geometry("400x450+600+150") self.resizable(0,0) # 不能改变大小 self.userinfo=0 # 加载控件 self.setup_UI() def setup_UI(self): # 加载一个pane self.Pane_detail = PanedWindow(self,width = 380,height = 410) self.Pane_detail.place(x = 10,y = 20) self.Style02 = Style(self.Pane_detail)#指定窗体,不指定则不显示样式 self.Style02.configure("TPanedwindow") self.Style02.configure("detail.TLabel", font=("微软雅黑", 16, "bold"),) self.Style02.configure("detail.TButton", font=("微软雅黑", 16, "bold")) self.Style02.configure("TEntry", font=("微软雅黑", 16, "bold"), width=10) self.Style02.configure("TRadiobutton", font=("微软雅黑", 16, "bold")) # 添加属性 # 第一排:学号 self.Label_sno = Label(self.Pane_detail,text = "学号:",style="detail.TLabel") self.Label_sno.place(x=10,y=10) self.var_sno = StringVar() self.Entry_sno = Entry(self.Pane_detail,textvariable = self.var_sno,font=("微软雅黑", 16,"bold"),width = 11) self.Entry_sno.place(x=80,y=8) # 姓名 self.Label_name = Label(self.Pane_detail, text="姓名:",style="detail.TLabel") self.Label_name.place(x=10, y=60) self.var_name = StringVar() self.Entry_name = Entry(self.Pane_detail, textvariable=self.var_name, font=("微软雅黑", 16, "bold"), width=8) self.Entry_name.place(x=80, y=58) # 性别 self.Label_gender = Label(self.Pane_detail,text = "性别:",style="detail.TLabel").place(x=10,y = 110) self.var_gender = IntVar() self.Radio_man = Radiobutton(self.Pane_detail,text="男",variable = self.var_gender,value = 1) self.Radio_man.place(x=80,y = 108) self.Radio_woman = Radiobutton(self.Pane_detail, text="女", variable=self.var_gender, value=2) self.Radio_woman.place(x=130, y=108) # 专业: self.Label_pro = Label(self.Pane_detail, text="专业:",style="detail.TLabel") self.Label_pro.place(x=10, y=160) self.var_pro = StringVar() self.Entry_pro = Entry(self.Pane_detail, textvariable=self.var_pro, font=("微软雅黑", 16, "bold"), width=15) self.Entry_pro.place(x=80, y=158) # 班级 self.Label_class = Label(self.Pane_detail, text="班级:",style="detail.TLabel") self.Label_class.place(x=6, y=210) self.var_class = StringVar() self.Entry_class = Entry(self.Pane_detail, textvariable=self.var_class, font=("微软雅黑", 16, "bold"), width=15) self.Entry_class.place(x=80, y=210) # 宿舍号 self.Label_sushehao = Label(self.Pane_detail, text="宿舍号:",style="detail.TLabel") self.Label_sushehao.place(x=10, y=260) self.var_sushehao = StringVar() self.Entry_sushehao = Entry(self.Pane_detail, textvariable=self.var_sushehao, font=("微软雅黑", 16, "bold"), width=7) self.Entry_sushehao.place(x=85, y=258) # 手机号码 self.Label_mobile = Label(self.Pane_detail, text="手机号码:",style="detail.TLabel") self.Label_mobile.place(x=10, y=310) self.var_mobile = StringVar() self.Entry_mobile = Entry(self.Pane_detail, textvariable=self.var_mobile, font=("微软雅黑", 16, "bold"), width=11) self.Entry_mobile.place(x=120, y=308) # 放置按钮 self.Button_save = Button(self, text="保存", style="detail.TButton",command=self.add_student_detail) self.Button_save02 = Button(self, text="保存", style="detail.TButton",command=self.update_student_detail) def show_save(self,all_student_list): self.Button_save.place(x=80, y=388) self.all_student_list=all_student_list def tube(self,all_student_list): self.all_student_list=all_student_list def load_student_detail(self,current_student_list,flag,index): if len(current_student_list) == 0: return else: self.var_sno.set(current_student_list[0]) # 学号 self.var_name.set(current_student_list[1]) if "男" in current_student_list[2]: self.var_gender.set(1) else: self.var_gender.set(2) self.var_pro.set(current_student_list[3]) self.var_class.set(current_student_list[4]) self.var_sushehao.set(current_student_list[5]) self.var_mobile.set(current_student_list[6]) if flag==1: # 控制控件的状态 self.Button_save.place_forget() self.Entry_sno["state"] = DISABLED self.Entry_name["state"] = DISABLED self.Radio_man["state"] = DISABLED self.Radio_woman["state"] = DISABLED self.Entry_class["state"] = DISABLED self.Entry_mobile["state"] = DISABLED self.Entry_sushehao["state"] = DISABLED self.Entry_pro["state"] = DISABLED else: self.index = index self.Button_save02.place(x=80, y=388) def add_student_detail(self): temp_list = [] if len(str(self.Entry_sno.get()).strip()) == 0: showinfo("系统消息", "学号不能为空!") else: temp_list.append(str(self.Entry_sno.get()).strip()) temp_list.append(str(self.Entry_name.get()).strip()) if self.var_gender.get() == 1: temp_list.append("男") else: temp_list.append("女") temp_list.append(str(self.Entry_pro.get()).strip()) temp_list.append(str(self.Entry_class.get()).strip()) temp_list.append(str(self.Entry_sushehao.get()).strip()) temp_list.append(str(self.Entry_mobile.get()).strip()) self.all_student_list.append(temp_list) self.userinfo=1 # 提醒添加成功 showinfo("系统消息", "学生信息添加成功") # 关闭窗体 self.destroy() def update_student_detail(self): temp_list = [] if len(str(self.Entry_sno.get()).strip()) == 0: showinfo("系统消息", "学号不能为空!") else: temp_list.append(str(self.Entry_sno.get()).strip()) temp_list.append(str(self.Entry_name.get()).strip()) if self.var_gender.get() == 1: temp_list.append("男") else: temp_list.append("女") temp_list.append(str(self.Entry_pro.get()).strip()) temp_list.append(str(self.Entry_class.get()).strip()) temp_list.append(str(self.Entry_sushehao.get()).strip()) temp_list.append(str(self.Entry_mobile.get()).strip()) self.all_student_list[self.index]=temp_list self.userinfo = 1 # 提醒添加成功 showinfo("系统消息", "学生信息修改成功") # 关闭窗体 self.destroy() if __name__ == '__main__': this_window = DetailWindow() this_window.mainloop()
6.3大家也可以到我分享网盘里直接下载源码哦
链接:https://pan.baidu.com/s/1il2IK1IJv0EZblcaYPZVhg
提取码:aygb