基于Python的tkinter、pymysql等模块,连接到MySQL数据库,对表记录进行增改查等操作,并展示到相应窗体列表控件中,实现对学生信息、成绩的管理。
数据库:通过score.csv导入表结构,如示例所示
背景图片:hxd.png,主界面背景
代码等资源链接:
基于python的tkinter模块的学生管理系统-MySQL文档类资源-CSDN文库
链接:https://pan.baidu.com/s/1YgS6GqTv6AZb3-SEYnHrYA
提取码:n208
1)将背景图片和代码放到同一文件夹下
2)安装MySQL、Navicat,在Navicat中连接到MySQL数据库
3)创建名为stu的数据库(或者修改代码中的连接数据库函数的数据库名)
4)将所给的score.csv通过表导入向导导入,若已有同名表,在导入时重命名目标表,并修改代码中表名称(或者按上图列名顺序自行建表)
5)将代码中的连接数据库函数的MySQL密码改为自己电脑MySQL 的密码
布局:父窗口包含学生信息、成绩信息按钮,点击后跳转到对应的顶层窗口
布局:学生信息顶层窗口包含对学生信息的增改查等操作,并将结果展示到列表控件
布局:学生成绩顶层窗口包含对成绩信息的增改查等操作,并将结果展示到列表控件
方法:通过pymysql模块连接到数据库
# 连接数据库
def consql(self):
# 链接数据库mysql,密码为mysql密码,数据库为stu,根据自身电脑调整,其他为默认值如下
con = pymysql.connect(host='localhost',
user='root',
password='***',
database='stu')
return con
# 创建游标
def cursql(self,con):
cur = con.cursor()
return cur
方法:通过tkinter模块创建窗口,并设置页面布局
# 创建父窗口
def createWindow(self):
self.window.title('学生管理系统') # 窗口名为'学生管理系统'
self.window.geometry('500x400') # 窗口宽*高为500x400,window.geometry('axb+c+d')四个参数分别为:宽、高,以及左、上的像素坐标
# # 背景图片
canvas_root = tk.Canvas(self.window, width=500, height=400) # 创建画布宽*高为500x400,像素大小
im = Image.open('hxd.png').resize((500, 400)) # 传入照片并将大小重置,宽*高为500x400
imtk=ImageTk.PhotoImage(im) # 创建一个Tkinter兼容的照片图像
canvas_root.create_image(250, 200, image=imtk) # 将图像添加到画布
canvas_root.pack() # 布局管理器
# command若想传入参数且不自动执行需要格式为 command = lambda:function(1)
tk.Button(self.window, text='学生信息', command=self.stu_info).place(relx=0.05, rely=0.05, relwidth=0.2) # 在父窗口添加'学生信息'按钮,执行stu_info函数的内容
tk.Button(self.window, text='成绩信息', command=self.stu_score).place(relx=0.3, rely=0.05, relwidth=0.2) # relx, rely : 水平和垂直偏移为0.0和1.0之间浮动,relwidth : 宽度为0.0和1.0之间浮动,相对于父容器
self.window.mainloop() # 窗口进入事件循环,可以理解为保持窗口运行,否则界面不展示
代码说明:
1)place()可以指定组件大小以及摆放位置,height、width参数表示控件自身的高度和宽度,relheight、relwidth 参数表示控件高度和宽度相对于根窗体高度和宽度的比例
5.2.2.1学生信息顶层窗口
## 学生信息的顶层窗口
def stu_info(self):
if not self.handle: # 只有handle为False时(代表无该窗口存在)才能执行建立窗口的语句
self.handle = True
top = tk.Toplevel(self.window) # 创建顶层窗口
top.geometry('900x600') # 宽*高
self.window.withdraw()
tk.Label(top, text='学号:').grid(row=0, column=0, pady=5) # 创建学号标签,pady:控件与外边框的竖直距离,为5
tk.Label(top, text='姓名:').grid(row=1, column=0, pady=5)
tk.Label(top, text='性别:').grid(row=2, column=0, pady=5)
tk.Label(top, text='年龄:').grid(row=3, column=0, pady=5)
tk.Entry(top, textvariable=self.id).grid(row=0, column=1, pady=5, ipadx=60) # 接受entry输入框中的单行文本字符串,将id与entry绑定,ipady:控件内文字与控件边框的竖直距离,为60
tk.Entry(top, textvariable=self.name).grid(row=1, column=1, pady=5, ipadx=60)
tk.Entry(top, textvariable=self.sex).grid(row=2, column=1, pady=5, ipadx=60)
tk.Entry(top, textvariable=self.age).grid(row=3, column=1, pady=5, ipadx=60)
tk.Button(top, text='显示学生信息', command=lambda: self.show_stu_info(tree)).grid(row=0, column=2, padx=200,
ipadx=50)
tk.Button(top, text='查询学生信息', command=lambda: self.search_stu_info(tree)).grid(row=1, column=2, padx=200,
ipadx=50)
tk.Button(top, text='添加学生信息', command=lambda: self.add_stu_info(tree)).grid(row=2, column=2, padx=200,
ipadx=50)
# 将Button控件查询结果展示到Treeview列表控件
tree = ttk.Treeview(top, show='headings', column=('id', 'name', 'sex', 'age')) # show 限制显示的内容为
tree.place(rely=0.35, width=800, relheight=0.6)
tree.column('id', width=150, anchor="center") # 列的名称或者标识为id,列宽为150,居中对齐
tree.column('name', width=200, anchor="center")
tree.column('sex', width=100, anchor="center")
tree.column('age', width=150, anchor="center")
tree.heading('id', text='学号') #设置表头,其文本为学号
tree.heading('name', text='姓名')
tree.heading('sex', text='性别')
tree.heading('age', text='年龄')
top.title("学生信息")
top.protocol("WM_DELETE_WINDOW", lambda: self.quit(top)) # 点击窗口关闭按钮时,自动调用quit函数,将回调函数与"WM_DELETE_WINDOW"绑定
代码说明:
1)grid()以行和列(网格)形式对控件进行排列,ipadx,ipady参数表示组件与内容和组件边框的距离,padx,pady参数用于控制组件之间的上下、左右的距离;
2)command参数表示用来执行按钮关联的回调函数。当按钮被点击时,执行该函数
3)tree.column()查询或者修改指定列的配置,id参数可以是整数,也可以列的别名
4)tree.heading()设置或者查询表头行的配置参数,text参数指在表头显示文本
5.2.2.2成绩信息顶层窗口
## 学生成绩的顶层窗口
def stu_score(self):
if not self.handle: # 只有handle为False时(代表无该窗口存在)才能执行建立窗口的语句
self.handle = True
top = tk.Toplevel(self.window)
top.geometry('900x600') # 宽*高
self.window.withdraw() # 隐藏窗口
tk.Label(top, text='学号:').grid(row=0, column=0, pady=5)
tk.Label(top, text='成绩:').grid(row=1, column=0, pady=5)
tk.Entry(top, textvariable=self.id).grid(row=0, column=1, pady=5, ipadx=60)
tk.Entry(top, textvariable=self.score).grid(row=1, column=1, pady=5, ipadx=60)
tk.Button(top, text='查询学生成绩', command=lambda: self.search_stu_score(tree)).grid(row=0, column=2, padx=200,
ipadx=50)
tk.Button(top, text='修改学生成绩', command=lambda: self.modify_stu_score(tree)).grid(row=1, column=2, padx=200,
ipadx=50)
# 将Button控件查询结果展示到Treeview列表控件
tree = ttk.Treeview(top, show='headings', column=('id', 'name', 'score'))
tree.place(rely=0.35, width=800, relheight=0.6)
tree.column('id', width=150, anchor="center")
tree.column('name', width=200, anchor="center")
tree.column('score', width=150, anchor="center")
tree.heading('id', text='学号')
tree.heading('name', text='姓名')
tree.heading('score', text='成绩')
top.title("学生成绩")
top.protocol("WM_DELETE_WINDOW", lambda: self.quit(top)) # 点击窗口关闭按钮时,自动调用quit函数,将回调函数与"WM_DELETE_WINDOW"绑定
# 展示所有学生信息
def show_stu_info(self, tree):
# 先清除原始数据
x = tree.get_children() # 返回列表的子节点
for item in x:
#print(item)
tree.delete(item)
# 连接数据库
con = self.consql()
# 创建游标
cur = self.cursql(con)
cur.execute("select * from score order by id") # 查询score表中的数据
lst = cur.fetchall() # 获取列表嵌套元组(全部数据),cur.fetchone()获取的是元组(单行数据)
# treeview的插入方法
for item in lst:
tree.insert("", 'end', values=item) # end表示插入到表格末尾,插入 学号,姓名,性别,年龄
cur.close()
con.close()
代码说明:
1)tree. get_children()返回列表的子节点
2)lst=cur.fetchall()取出操作返回的所有的行
3)tup= cur.fetchone()取出一行
功能实现:通过点击学生信息界面的显示学生信息按钮调用函数,如下图所示
# 查询学生信息
def search_stu_info(self, tree):
x = tree.get_children()
for item in x:
tree.delete(item)
# 连接数据库
con = self.consql()
# 创建游标
cur = self.cursql(con)
if self.id.get() != "":
result = cur.execute('select * from score where id = %s',self.id.get()) # 查询,通过输入框中的id值查询
if result < 1:
messagebox.showerror(title='提示', message='未找到相关学生') # 打开一个错误提示对话框
else:
lst = cur.fetchall()
for item in lst:
tree.insert("", 'end', values=item)
cur.close()
con.close()
else:
messagebox.showerror(title='提示', message='请输入学号!')
代码说明:
1)messagebox.showerror() 打开一个错误提示对话框
功能实现:输入学号后,通过点击该学生信息界面的查询学生信息按钮调用函数,如下图所示
# 添加学生信息
def add_stu_info(self, tree):
x = tree.get_children()
for item in x:
tree.delete(item)
ans = messagebox.askyesno(title='提示', message='是否进行当前操作') # 打开一个“是/否”的对话框
if ans is True:
if self.id.get() == "" or self.name.get() == ""or self.age.get() == "" or self.sex.get() == "" :
messagebox.showerror(title='提示', message='请输入完整信息!')
else:
# 连接数据库
con = self.consql()
# 创建游标
cur = self.cursql(con)
# 检验ID是否已经存在
result = cur.execute('select * from score where id = %s',self.id.get()) # 查询
if result > 0:
messagebox.showerror(title="提示", message="学号已存在!")
else:
try:
cur.execute('insert into score(id,name,sex,age) values (%s, %s, %s, %s) ',
(self.id.get(),self.name.get(), self.sex.get(), self.age.get())) # 插入
con.commit() # 提交到数据库
messagebox.showinfo(title="提示", message="添加成功!") #打开一个信息提示对话框
tree.insert("", 'end', values=(self.id.get(),self.name.get(), self.sex.get(), self.age.get()))
except:
con.rollback() # 事务回滚,撤销更改
messagebox.showerror(title='提示', message='添加失败,请检查是否输入信息过长或者出现格式错误')
cur.close()
con.close()
代码说明:
1)messagebox.askyesno() 打开一个“是/否”的对话框
2)messagebox.showinfo() 打开一个信息提示对话框
功能实现:输入学号、姓名、性别、年龄等信息后,通过点击该学生信息界面的添加学生信息按钮调用函数,选择“是”进行当前操作,添加成功后会提示添加成功,如下图所示
# 查询学生成绩
def search_stu_score(self, tree):
x = tree.get_children()
for item in x:
tree.delete(item)
# 连接数据库
con = self.consql()
# 创建游标
cur = self.cursql(con)
if self.id.get() != "":
result = cur.execute('select * from score where id = %s',self.id.get())
if result < 1:
messagebox.showerror(title='提示', message='未找到相关学生')
else:
lst = cur.fetchall()
for item in lst:
tree.insert("", 'end', values=(item[0],item[1],item[-1])) # 插入学号,姓名,成绩
cur.close()
con.close()
else:
messagebox.showerror(title='提示', message='请输入学号!')
功能实现:输入学号后,通过点击学生信息界面的查询学生成绩按钮调用函数,如下图所示
# 修改学生成绩
def modify_stu_score(self, tree):
x = tree.get_children()
for item in x:
tree.delete(item)
ans = messagebox.askyesno(title='提示', message='是否进行当前操作')
if ans is True:
if self.id.get() == "" and self.score.get() == "":
messagebox.showerror(title='提示', message='请输入完整信息!')
else:
# 连接数据库
con = self.consql()
# 创建游标
cur = self.cursql(con)
try:
cur.execute('update score set score=%s where id=%s',(self.score.get(), self.id.get())) # 修改
messagebox.showinfo(title='提示', message='修改成功!')
con.commit()
self.search_stu_score(tree)
except:
con.rollback()
messagebox.showerror(title='提示', message='修改失败!请检查信息格式!')
con.close()
cur.close()
功能实现:输入学号、成绩后,通过点击学生信息界面的修改学生成绩按钮调用函数,如下图所示
1)con=pymysql.connect(host='***', # 要连接的主机地址,默认为localhost
user='***', # 用于登录的数据库用户,默认为root
password='***', # 密码
database='***', # 要连接的数据库)
使用结束后用close()关闭连接
1)cur=con.cursor() 使用结束后用close()关闭游标对象
1)cur.execute(query)
1)con.commit() 如果没有设为自动提交,则每次操作后必须提交事务,否则操作无效。
1)lst=cur.fetchall() 取出操作返回的所有的行
2)tup= cur.fetchone() 取出一行
1)tkinter.Tk() 创建一个主窗口对象,使用mainloop() 设置主窗口主循环,使窗口循环显示
2)tkinter.Toplevel() 创建顶层窗口
1)tkinter.Lable() 主要用来显示窗口中的文本或者图像,text参数用来指定 Lable 显示的文本
2)实现布局管理可以用grid()以行和列(网格)形式对控件进行排列,ipadx,ipady参数表示组件与内容和组件边框的距离,padx,pady参数用于控制组件之间的上下、左右的距离;place()可以指定组件大小以及摆放位置,height、width参数表示控件自身的高度和宽度,relheight、relwidth 参数表示控件高度和宽度相对于根窗体高度和宽度的比例
1)tkinter.Button() 实现程序与用户交互的主要控件,command参数用来执行按钮关联的回调函数。当按钮被点击时,执行该函数
1)tkinter.Entry() 允许用户输入内容,show参数指定文本框内容以何种样式的字符显示,textvariable参数表示输入框内值,也称动态字符串,使用 StringVar() 对象来设置,而 text 为静态字符串对象
1)tree=tkinter. ttk.Treeview()
2)tree.column() 查询或者修改指定列的配置,id参数可以是整数,也可以列的别名
3)tree.heading() 设置或者查询表头行的配置参数,text参数指在表头显示文本
4)tree. get_children() 返回列表的子节点
1)messagebox.askyesno() 打开一个“是/否”的对话框
2)messagebox.showerror() 打开一个错误提示对话框
3)messagebox.showinfo() 打开一个信息提示对话框