0.作品描述

基于Python的tkinter、pymysql等模块,连接到MySQL数据库,对表记录进行增改查等操作,并展示到相应窗体列表控件中,实现对学生信息、成绩的管理。

1.思维导图

学生系统管理python 学生系统管理ppt_数据库

2.数据源

数据库:通过score.csv导入表结构,如示例所示

学生系统管理python 学生系统管理ppt_python_02

背景图片:hxd.png,主界面背景

 

 链接:https://pan.baidu.com/s/1YgS6GqTv6AZb3-SEYnHrYA 

提取码:n208

3.数据源加载

1)将背景图片和代码放到同一文件夹下

2)安装MySQL、Navicat,在Navicat中连接到MySQL数据库

3)创建名为stu的数据库(或者修改代码中的连接数据库函数的数据库名)

4)将所给的score.csv通过表导入向导导入,若已有同名表,在导入时重命名目标表,并修改代码中表名称(或者按上图列名顺序自行建表)

5)将代码中的连接数据库函数的MySQL密码改为自己电脑MySQL 的密码

4.展示界面

4.1学生管理系统主界面

布局:父窗口包含学生信息、成绩信息按钮,点击后跳转到对应的顶层窗口

学生系统管理python 学生系统管理ppt_python_03

4.2学生信息界面

布局:学生信息顶层窗口包含对学生信息的增改查等操作,并将结果展示到列表控件

学生系统管理python 学生系统管理ppt_python_04

4.3学生成绩界面

布局:学生成绩顶层窗口包含对成绩信息的增改查等操作,并将结果展示到列表控件

学生系统管理python 学生系统管理ppt_mysql_05

5.主体内容

5.1连接数据库

方法:通过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

5.2创建窗体

方法:通过tkinter模块创建窗口,并设置页面布局

5.2.1父窗口

# 创建父窗口
    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顶层窗口

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"绑定

5.3数据库记录增改查及展示

5.3.1学生信息显示

# 展示所有学生信息
    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()取出一行

功能实现:通过点击学生信息界面的显示学生信息按钮调用函数,如下图所示

学生系统管理python 学生系统管理ppt_python_06

5.3.2学生信息查询

# 查询学生信息
    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()      打开一个错误提示对话框

功能实现:输入学号后,通过点击该学生信息界面的查询学生信息按钮调用函数,如下图所示

学生系统管理python 学生系统管理ppt_python_07

5.3.3学生信息添加

# 添加学生信息
    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()        打开一个信息提示对话框

功能实现:输入学号、姓名、性别、年龄等信息后,通过点击该学生信息界面的添加学生信息按钮调用函数,选择“是”进行当前操作,添加成功后会提示添加成功,如下图所示

        

学生系统管理python 学生系统管理ppt_python_08

学生系统管理python 学生系统管理ppt_python_09

学生系统管理python 学生系统管理ppt_mysql_10

5.3.4学生成绩查询

# 查询学生成绩
    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='请输入学号!')

功能实现:输入学号后,通过点击学生信息界面的查询学生成绩按钮调用函数,如下图所示

学生系统管理python 学生系统管理ppt_mysql_11

5.3.5学生成绩修改

# 修改学生成绩
    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()

功能实现:输入学号、成绩后,通过点击学生信息界面的修改学生成绩按钮调用函数,如下图所示

学生系统管理python 学生系统管理ppt_学生系统管理python_12

6.知识点

6.1数据库操作

6.1.1连接数据库

1)con=pymysql.connect(host='***',          # 要连接的主机地址,默认为localhost

                                      user='***',          # 用于登录的数据库用户,默认为root

                                      password='***',        # 密码

                                      database='***',      # 要连接的数据库)

使用结束后用close()关闭连接

6.1.2创建游标

1)cur=con.cursor()  使用结束后用close()关闭游标对象

6.1.3执行sql语句

1)cur.execute(query)

6.1.4事务提交

1)con.commit()  如果没有设为自动提交,则每次操作后必须提交事务,否则操作无效。

6.1.5获取查询结果

1)lst=cur.fetchall()  取出操作返回的所有的行

2)tup= cur.fetchone()  取出一行

6.2窗体构建

6.2.1创建窗体

1)tkinter.Tk()  创建一个主窗口对象,使用mainloop()      设置主窗口主循环,使窗口循环显示

2)tkinter.Toplevel()  创建顶层窗口

6.2.2创建标签

1)tkinter.Lable()  主要用来显示窗口中的文本或者图像,text参数用来指定 Lable 显示的文本

2)实现布局管理可以用grid()以行和列(网格)形式对控件进行排列,ipadx,ipady参数表示组件与内容和组件边框的距离,padx,pady参数用于控制组件之间的上下、左右的距离;place()可以指定组件大小以及摆放位置,height、width参数表示控件自身的高度和宽度,relheight、relwidth     参数表示控件高度和宽度相对于根窗体高度和宽度的比例

6.2.3创建按钮

1)tkinter.Button()  实现程序与用户交互的主要控件,command参数用来执行按钮关联的回调函数。当按钮被点击时,执行该函数

6.2.4创建输入框

1)tkinter.Entry()  允许用户输入内容,show参数指定文本框内容以何种样式的字符显示,textvariable参数表示输入框内值,也称动态字符串,使用 StringVar() 对象来设置,而 text 为静态字符串对象

6.2.5创建列表

1)tree=tkinter. ttk.Treeview()

2)tree.column()  查询或者修改指定列的配置,id参数可以是整数,也可以列的别名

3)tree.heading()  设置或者查询表头行的配置参数,text参数指在表头显示文本

4)tree. get_children()  返回列表的子节点

6.2.6创建消息对话框

1)messagebox.askyesno() 打开一个“是/否”的对话框

2)messagebox.showerror()      打开一个错误提示对话框

3)messagebox.showinfo()        打开一个信息提示对话框