Python+mysql+tkinter+matplotlib的可视化学生成绩管理系统课程设计

发布时间 2023-06-26 09:09:09作者: 快乐野指针

使用模块要求:

tkinter、numpy、openpyxl、matplotlib、pymysql、re、time;其中matplotlib用于绘制统计图

开发工具:pycharm专业版、python3.7、mysql8.0

需要咨询、源码、定做、QQ扫码加:
https://img-mid.csdnimg.cn/release/static/image/mid/ask/153137086786150.jpg

点击此处链接、并扫描加QQ好友

 需要咨询、源码、定做课设(C语言数据结构、python)

加QQ:3125841747

更对课设请访问CSDN主页,直达链接:https://blog.csdn.net/m0_56604317?spm=1000.2115.3001.5343

 

运行效果:

主页面:

 教师端主要功能:

 教师端登录后的效果——个人资料页面:

  

教师端登录后的效果——学生查询页面:

 

  教师端登录后的效果——成绩查询页面:

 

 教师端登录后的效果——成绩分析页面:

 

成绩分析页面——课程成绩分析(统计图):

 

各班级创建分析页面——统计图:

班级综合成绩评定页面——扇形统计图:

 修改密码页面:

课程管理页面——根据学院、考试方式进行添加或删除课程:

 Teacherpage.py页面代码如下:

from tkinter import *
from tkinter import messagebox, filedialog
from tkinter.ttk import *

import openpyxl as openpyxl

import AddCoursePage
import AddScorePage
import ClassGradeAnalysis
import ComprehensivePerformanceEvaluation
import CourseScoreAnalysis
import Dao
import DeleteCoursePage
import DeleteScorePage
import Login
import UpdateCoursePage

import AddStudentPage
import DeleteStudentPage
import UpdateScorePage
import UpdateStudentPage

import numpy as np
import matplotlib.pyplot as plt

class WinGUI(Tk):
    def __init__(self):
        super().__init__()
        self.__win()
        self.tk_label_title = self.__tk_label_title()
        self.tk_label_current_user = self.__tk_label_current_user()
        self.tk_tabs_content = Frame_content(self)
        self.tk_button_logout_user = self.__tk_button_logout_user()

    def __win(self):
        self.title("教师端")
        # 设置窗口大小、居中
        width = 1000
        height = 600
        screenwidth = self.winfo_screenwidth()
        screenheight = self.winfo_screenheight()
        geometry = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
        self.geometry(geometry)
        self.resizable(width=False, height=False)
        self.iconbitmap('logo.ico')

    def __tk_label_title(self):
        label = Label(self, text="学生成绩管理系统", anchor="center")
        label.place(x=0, y=0, width=800, height=100)
        return label

    def __tk_label_current_user(self):
        label = Label(self, text="当前用户:admin", anchor="center")
        label.place(x=800, y=70, width=150, height=30)
        return label

    def __tk_button_logout_user(self):
        btn = Button(self, text="退出")
        btn.place(x=950, y=70, width=50, height=30)
        return btn


class Frame_content(Notebook):
    def __init__(self, parent):
        super().__init__(parent)
        self.__frame()

    def __frame(self):
        self.tk_tabs_content_0 = Frame_content_0(self)
        self.add(self.tk_tabs_content_0, text="个人资料")

        self.tk_tabs_content_1 = Frame_content_1(self)
        self.add(self.tk_tabs_content_1, text="学生查询")

        self.tk_tabs_content_2 = Frame_content_2(self)
        self.add(self.tk_tabs_content_2, text="成绩查询")

        self.tk_tabs_content_3 = Frame_content_3(self)
        self.add(self.tk_tabs_content_3, text="成绩分析")

        self.tk_tabs_content_4 = Frame_content_4(self)
        self.add(self.tk_tabs_content_4, text="修改密码")

        self.tk_tabs_content_5 = Frame_content_5(self)
        self.add(self.tk_tabs_content_5, text="课程管理")

        self.place(x=0, y=100, width=1000, height=500)


class Frame_content_0(Frame):
    def __init__(self, parent):
        super().__init__(parent)
        self.__frame()
        self.tk_label_tea_number = self.__tk_label_tea_number()
        self.tk_input_tea_number = self.__tk_input_tea_number()
        self.tk_label_tea_name = self.__tk_label_tea_name()
        self.tk_input_tea_name = self.__tk_input_tea_name()
        self.tk_label_tea_gender = self.__tk_label_tea_gender()
        self.tk_select_tea_gender = self.__tk_select_tea_gender()
        self.tk_label_tea_identity = self.__tk_label_tea_identity()
        self.tk_input_tea_identity = self.__tk_input_tea_identity()
        self.tk_label_tea_email = self.__tk_label_tea_email()
        self.tk_input_tea_email = self.__tk_input_tea_email()
        self.tk_button_tea_update = self.__tk_button_tea_update()
        self.tk_button_tea_reset = self.__tk_button_tea_reset()

    def __frame(self):
        self.place(x=0, y=100, width=1000, height=500)

    def __tk_label_tea_number(self):
        label = Label(self, text="工号", anchor="e")
        label.place(x=360, y=40, width=100, height=30)
        return label

    def __tk_input_tea_number(self):
        self.tea_number = StringVar(self)
        ipt = Entry(self,  text=self.tea_number)
        ipt.place(x=490, y=40, width=150, height=30)
        ipt.config(stat='disable')
        return ipt

    def __tk_label_tea_name(self):
        label = Label(self, text="姓名", anchor="e")
        label.place(x=360, y=110, width=100, height=30)
        return label

    def __tk_input_tea_name(self):
        self.tea_name = StringVar(self)
        ipt = Entry(self,  text=self.tea_name)
        ipt.place(x=490, y=110, width=150, height=30)
        return ipt

    def __tk_label_tea_gender(self):
        label = Label(self, text="性别", anchor="e")
        label.place(x=360, y=180, width=100, height=30)
        return label

    def __tk_select_tea_gender(self):
        cb = Combobox(self, state='readonly')
        cb['values'] = ("", "")
        cb.place(x=490, y=180, width=150, height=30)
        return cb

    def __tk_label_tea_identity(self):
        label = Label(self, text="身份证号", anchor="e")
        label.place(x=360, y=250, width=100, height=30)
        return label

    def __tk_input_tea_identity(self):
        self.tea_identify = StringVar(self)
        ipt = Entry(self,  text=self.tea_identify)
        ipt.place(x=490, y=250, width=150, height=30)
        return ipt

    def __tk_label_tea_email(self):
        label = Label(self, text="电子邮箱", anchor="e")
        label.place(x=360, y=320, width=100, height=30)
        return label

    def __tk_input_tea_email(self):
        self.tea_email = StringVar(self)
        ipt = Entry(self,  text=self.tea_email)
        ipt.place(x=490, y=320, width=150, height=30)
        return ipt

    def __tk_button_tea_update(self):
        btn = Button(self, text="修改")
        btn.place(x=400, y=390, width=80, height=30)
        return btn

    def __tk_button_tea_reset(self):
        btn = Button(self, text="重置")
        btn.place(x=520, y=390, width=80, height=30)
        return btn


class Frame_content_1(Frame):
    def __init__(self, parent):
        super().__init__(parent)
        self.__frame()
        self.tk_table_student_query = self.__tk_table_student_query()
        self.tk_input_stu_name = self.__tk_input_stu_name()
        self.tk_select_box_stu_gender = self.__tk_select_box_stu_gender()
        self.tk_button_stu_search = self.__tk_button_stu_search()
        self.tk_button_addStudent = self.__tk_button_addStudent()
        self.tk_button_delete_student = self.__tk_button_delete_student()
        self.tk_button_stu_refresh = self.__tk_button_stu_refresh()
        self.tk_button_studentinfo_export = self.__tk_button_studentinfo_export()

    def __frame(self):
        self.place(x=0, y=100, width=1000, height=500)

    def __tk_table_student_query(self):
        # 表头字段 表头宽度
        self.tk_table_student_manage_columns = {"ID": 50, "学号": 100, "姓名": 150, '性别': 100, '身份证号': 300, '班级': 100, '邮箱': 200}
        # 初始化表格 表格是基于Treeview,tkinter本身没有表格。show="headings" 为隐藏首列。
        tk_table = Treeview(self, show="headings", columns=list(self.tk_table_student_manage_columns))
        for text, width in self.tk_table_student_manage_columns.items():  # 批量设置列属性
            tk_table.heading(text, text=text, anchor='center')
            tk_table.column(text, anchor='center', width=width, stretch=False)  # stretch 不自动拉伸

        # 插入数据示例
      
        #
        # # 导入初始数据
        self.tk_student_table_dataset = Dao.getAllStudents()
        if self.tk_student_table_dataset.get("code") == 0:
            if self.tk_student_table_dataset.get("data"):
                print(self.tk_student_table_dataset.get("data"))
                for values in self.tk_student_table_dataset.get("data"):
                    tk_table.insert('', END, values=list(values.values()))
            else:
                print("未查询到数据!")
        else:
            print("数据查询异常!")

        tk_table.place(x=0, y=60, width=1000, height=415)
        return tk_table

    def __tk_input_stu_name(self):
        ipt = Entry(self)
        ipt.place(x=360, y=10, width=150, height=30)
        return ipt

    def __tk_select_box_stu_gender(self):
        cb = Combobox(self, state="readonly")
        cb['values'] = ("请选择性别", "", "")
        cb.place(x=540, y=10, width=150, height=30)
        cb.current(0)
        return cb

    def __tk_button_stu_search(self):
        btn = Button(self, text="搜索")
        btn.place(x=720, y=10, width=70, height=30)
        return btn

    def __tk_button_stu_refresh(self):
        btn = Button(self, text="刷新")
        btn.place(x=820, y=10, width=70, height=30)
        return btn

    def __tk_button_addStudent(self):
        btn = Button(self, text="添加学生")
        btn.place(x=50, y=10, width=100, height=30)
        return btn

    def __tk_button_delete_student(self):
        btn = Button(self, text="删除学生")
        btn.place(x=180, y=10, width=100, height=30)
        return btn

    def __tk_button_studentinfo_export(self):
        btn = Button(self, text="导出")
        btn.place(x=920, y=10, width=50, height=30)
        return btn


class Frame_content_2(Frame):
    def __init__(self, parent):
        super().__init__(parent)
        self.__frame()
        self.tk_table_stu_score = self.__tk_table_stu_score()
        self.tk_button_add_score = self.__tk_button_add_score()
        self.tk_button_delete_score = self.__tk_button_delete_score()
        self.tk_select_box_score_course_name = self.__tk_select_box_score_course_name()
        self.tk_select_box_score_nature = self.__tk_select_box_score_nature()
        self.tk_select_box_score_department = self.__tk_select_box_score_department()
        self.tk_button_stu_score_search = self.__tk_button_stu_score_search()
        self.tk_button_stu_score_export = self.__tk_button_stu_score_export()

    def __frame(self):
        self.place(x=0, y=100, width=1000, height=500)

    def __tk_table_stu_score(self):
        # 表头字段 表头宽度
        self.tk_table_stu_score_columns = {"#": 50, "学号": 70, "姓名": 80, "课程名称": 200, "课程性质": 100, "开课学院": 270, "考试方式": 80, "学分": 50, "成绩": 100}
        # 初始化表格 表格是基于Treeview,tkinter本身没有表格。show="headings" 为隐藏首列。
        tk_table = Treeview(self, show="headings", columns=list(self.tk_table_stu_score_columns))
        for text, width in self.tk_table_stu_score_columns.items():  # 批量设置列属性
            tk_table.heading(text, text=text, anchor='center')
            tk_table.column(text, anchor='center', width=width, stretch=False)  # stretch 不自动拉伸

        # 插入数据示例
        self.tk_score_table_dataset = Dao.searchStudentScore()
        # 导入初始数据
        if self.tk_score_table_dataset.get("code") == 0 and self.tk_score_table_dataset.get("data"):
            for data in self.tk_score_table_dataset.get("data"):
                tk_table.insert('', END, values=list(data.values()))

        tk_table.place(x=0, y=60, width=1000, height=415)
        return tk_table

    def __tk_button_add_score(self):
        btn = Button(self, text="添加成绩")
        btn.place(x=50, y=10, width=100, height=30)
        return btn

    def __tk_button_delete_score(self):
        btn = Button(self, text="删除成绩")
        btn.place(x=170, y=10, width=100, height=30)
        return btn

    def __tk_select_box_score_course_name(self):
        cb = Combobox(self, state="readonly")
        values = ["请选择课程名称"]
        for i in Dao.getAllCourses().get("data"):
            values.append(i.get("cname"))
        cb['values'] = values
        cb.current(0)
        cb.place(x=290, y=10, width=150, height=30)
        return cb

    def __tk_select_box_score_nature(self):
        cb = Combobox(self, state="readonly")
        values = ["请选择课程性质"]
        for i in Dao.getDataDictByType("nature").get("data"):
            values.append(i.get("v"))
        cb['values'] = values
        cb.current(0)
        cb.place(x=460, y=10, width=150, height=30)
        return cb

    def __tk_select_box_score_department(self):
        cb = Combobox(self, state="readonly")
        values = ["请选择开课学院"]
        for i in Dao.getAllDepartments().get("data"):
            values.append(i.get("v"))
        cb['values'] = values
        cb.current(0)
        cb.place(x=630, y=10, width=150, height=30)
        return cb

    def __tk_button_stu_score_search(self):
        btn = Button(self, text="搜索")
        btn.place(x=800, y=10, width=70, height=30)
        return btn

    def __tk_button_stu_score_export(self):
        btn = Button(self, text="导出")
        btn.place(x=890, y=10, width=70, height=30)
        return btn


class Frame_content_3(Frame):
    def __init__(self, parent):
        super().__init__(parent)
        self.__frame()
        self.tk_button_pieChart = self.__tk_button_pieChart()
        self.tk_button_columnChart = self.__tk_button_columnChart()
        self.tk_button_paratacticColumnChart = self.__tk_button_paratacticColumnChart()

    def __frame(self):
        self.place(x=0, y=100, width=1000, height=500)

    def __tk_button_columnChart(self):
        btn = Button(self, text="课程成绩分析")
        btn.place(x=80, y=50, width=150, height=70)
        return btn

    def __tk_button_paratacticColumnChart(self):
        btn = Button(self, text="班级成绩分析")
        btn.place(x=420, y=50, width=150, height=70)
        return btn

    def __tk_button_pieChart(self):
        btn = Button(self, text="综合成绩评定")
        btn.place(x=760, y=50, width=150, height=70)
        return btn


class Frame_content_4(Frame):
    def __init__(self, parent):
        super().__init__(parent)
        self.__frame()
        self.tk_label_original_pwd = self.__tk_label_original_pwd()
        self.tk_input_original_pwd = self.__tk_input_original_pwd()
        self.tk_label_new_pwd = self.__tk_label_new_pwd()
        self.tk_input_new_pwd = self.__tk_input_new_pwd()
        self.tk_label_confirm_pwd = self.__tk_label_confirm_pwd()
        self.tk_input_confirm_pwd = self.__tk_input_confirm_pwd()
        self.tk_button_update_tea_pwd = self.__tk_button_update_tea_pwd()

    def __frame(self):
        self.place(x=0, y=100, width=1000, height=500)

    def __tk_label_original_pwd(self):
        label = Label(self, text="原密码", anchor="e")
        label.place(x=360, y=40, width=100, height=30)
        return label

    def __tk_input_original_pwd(self):
        ipt = Entry(self, show='*')
        ipt.place(x=490, y=40, width=150, height=30)
        return ipt

    def __tk_label_new_pwd(self):
        label = Label(self, text="新密码", anchor="e")
        label.place(x=360, y=110, width=100, height=30)
        return label

    def __tk_input_new_pwd(self):
        ipt = Entry(self, show='*')
        ipt.place(x=490, y=110, width=150, height=30)
        return ipt

    def __tk_label_confirm_pwd(self):
        label = Label(self, text="确认密码", anchor="e")
        label.place(x=360, y=180, width=100, height=30)
        return label

    def __tk_input_confirm_pwd(self):
        ipt = Entry(self, show='*')
        ipt.place(x=490, y=180, width=150, height=30)
        return ipt

    def __tk_button_update_tea_pwd(self):
        btn = Button(self, text="修改")
        btn.place(x=450, y=260, width=100, height=30)
        return btn


class Frame_content_5(Frame):
    def __init__(self, parent):
        super().__init__(parent)
        self.__frame()
        self.tk_table_course_manage = self.__tk_table_course_manage()
        self.tk_button_add_course = self.__tk_button_add_course()
        self.tk_button_delete_course = self.__tk_button_delete_course()
        self.tk_select_box_course_department = self.__tk_select_box_course_department()
        self.tk_select_box_course_exam_method = self.__tk_select_box_course_exam_method()
        self.tk_button_course_search = self.__tk_button_course_search()
        self.tk_button_course_export = self.__tk_button_course_export()

    def __frame(self):
        self.place(x=0, y=100, width=1000, height=500)

    def __tk_table_course_manage(self):
        # 表头字段 表头宽度
        self.tk_table_course_manage_columns = {"课程号": 100, "课程名称": 200, "学分": 100, "课程性质": 200, "开课学院": 300, "考试方式": 100}
        # 初始化表格 表格是基于Treeview,tkinter本身没有表格。show="headings" 为隐藏首列。
        tk_table = Treeview(self, show="headings", columns=list(self.tk_table_course_manage_columns))
        for text, width in self.tk_table_course_manage_columns.items():  # 批量设置列属性
            tk_table.heading(text, text=text, anchor='center')
            tk_table.column(text, anchor='center', width=width, stretch=False)  # stretch 不自动拉伸

        # 插入数据示例
        self.tk_course_table_dataset = Dao.getAllCourses()
        # 导入初始数据
        if self.tk_course_table_dataset.get("code") == 0 and self.tk_course_table_dataset.get("data"):
            for data in self.tk_course_table_dataset.get("data"):
                tk_table.insert('', END, values=list(data.values()))

        tk_table.place(x=0, y=60, width=1000, height=415)
        return tk_table

    def __tk_button_add_course(self):
        btn = Button(self, text="添加课程")
        btn.place(x=50, y=10, width=100, height=30)
        return btn

    def __tk_button_delete_course(self):
        btn = Button(self, text="删除课程")
        btn.place(x=180, y=10, width=100, height=30)
        return btn

    def __tk_select_box_course_department(self):
        cb = Combobox(self, state="readonly")
        values = ["请选择开课学院"]
        for i in Dao.getAllDepartments().get("data"):
            values.append(i.get("v"))
        cb['values'] = values
        cb.current(0)
        cb.place(x=310, y=10, width=150, height=30)
        return cb

    def __tk_select_box_course_exam_method(self):
        cb = Combobox(self, state="readonly")
        values = ["请选择考试方式"]
        for i in Dao.getDataDictByType("exammethod").get("data"):
            values.append(i.get("v"))
        cb['values'] = values
        cb.current(0)
        cb.place(x=490, y=10, width=150, height=30)
        return cb

    def __tk_button_course_search(self):
        btn = Button(self, text="搜索")
        btn.place(x=670, y=10, width=100, height=30)
        return btn

    def __tk_button_course_export(self):
        btn = Button(self, text="导出")
        btn.place(x=800, y=10, width=100, height=30)
        return btn


class Win(WinGUI):
    def __init__(self, current_user):
        super().__init__()
        self.__event_bind()
        self.current_user = current_user
        self.uid = current_user.get("uid")
        self.tk_label_current_user['text'] = "当前用户:" + current_user.get("uname")
        self.tk_tabs_content.tk_tabs_content_0.tea_number.set(current_user.get("uid"))
        self.tk_tabs_content.tk_tabs_content_0.tea_name.set(current_user.get("uname"))
        self.tk_tabs_content.tk_tabs_content_0.tk_select_tea_gender.current(0 if current_user.get("ugender") == '' else 1)
        self.tk_tabs_content.tk_tabs_content_0.tea_identify.set(current_user.get("uidentify"))
        self.tk_tabs_content.tk_tabs_content_0.tea_email.set(current_user.get("uemail"))

    def logout(self):
        try:
            self.updateStudent.destroy()
            self.addInfo.destroy()
            self.delete.destroy()
        except Exception as e:
            print(e)
        messagebox.showwarning('提示', '欢迎下次使用!')
        self.destroy()
        login = Login.Win()
        login.mainloop()

    def updateStudentInfo(self, evt):
        current_focus = self.tk_tabs_content.tk_tabs_content_1.tk_table_student_query.focus()
        current_studentinfo = self.tk_tabs_content.tk_tabs_content_1.tk_table_student_query.set(current_focus)
        current_uid = current_studentinfo.get('学号')
        self.updateStudent = UpdateStudentPage.Win(current_uid)
        self.updateStudent.mainloop()
        print("<<TreeviewSelect>>事件未处理", evt)

    def updateTeacherInfo(self, evt):
        __tea_name = self.tk_tabs_content.tk_tabs_content_0.tk_input_tea_name.get()
        __tea_gender = self.tk_tabs_content.tk_tabs_content_0.tk_select_tea_gender.get()
        __tea_identify = self.tk_tabs_content.tk_tabs_content_0.tk_input_tea_identity.get()
        __tea_email = self.tk_tabs_content.tk_tabs_content_0.tk_input_tea_email.get()
        if not __tea_name or not __tea_gender or not __tea_identify or not __tea_email:
            messagebox.showinfo("提示", "必填项不能为空!")
            return
        if not re.match(r'^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$',
                        __tea_identify):
            messagebox.showinfo("提示", "身份证格式不合法!")
            return
        if not re.match(r'^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$', __tea_email):
            messagebox.showinfo("提示", "电子邮箱格式不合法!")
            return
        res = Dao.updateUser(self.uid, __tea_name, __tea_gender, __tea_identify, 0, __tea_email)
        messagebox.showinfo("提示", res.get("msg"))
        self.tk_label_current_user['text'] = "当前用户:" + __tea_name
        print("更新教师信息", evt)

    def resetTeacherInfo(self, evt):
        self.tk_tabs_content.tk_tabs_content_0.tea_name.set(self.current_user.get("uname"))
        self.tk_tabs_content.tk_tabs_content_0.tk_select_tea_gender.current(0 if self.current_user.get("ugender") == '' else 1)
        self.tk_tabs_content.tk_tabs_content_0.tea_identify.set(self.current_user.get("uidentify"))
        self.tk_tabs_content.tk_tabs_content_0.tea_email.set(self.current_user.get("uemail"))
        print("重置教师信息", evt)

    def searchStudentInfo(self, evt):
        for _ in map(self.tk_tabs_content.tk_tabs_content_1.tk_table_student_query.delete,
                     self.tk_tabs_content.tk_tabs_content_1.tk_table_student_query.get_children("")):
            pass
        value = self.tk_tabs_content.tk_tabs_content_1.tk_input_stu_name.get()
        num = self.tk_tabs_content.tk_tabs_content_1.tk_select_box_stu_gender.get()
        print(num, value)
        if num == '请选择性别':
            result = Dao.searchStudents(value, '')
        else:
            result = Dao.searchStudents(value, num)
        if result.get("code") == 0:
            if result.get("data"):
                # print(result.get("data"))
                for values in result.get("data"):
                    self.tk_tabs_content.tk_tabs_content_1.tk_table_student_query.insert('', END, values=list(values.values()))
            else:
                print("未查询到数据!")
        else:
            print("数据查询异常!")
        print("搜索学生信息", evt)

    def updateStudentScore(self, evt):
        current_item = self.tk_tabs_content.tk_tabs_content_2.tk_table_stu_score.set(self.tk_tabs_content.tk_tabs_content_2.tk_table_stu_score.focus())
        data = {
            "uid": current_item.get("学号"),
            "cname": current_item.get("课程名称"),
            "score": current_item.get("成绩")
        }
        updateScorePage = UpdateScorePage.Win(data)
        updateScorePage.mainloop()
        print("修改学生课程成绩", evt)

    def searchStuScore(self, evt):
        __score_manage = self.tk_tabs_content.tk_tabs_content_2
        __course_name = __score_manage.tk_select_box_score_course_name.get()
        __course_nature = __score_manage.tk_select_box_score_nature.get()
        __course_department = __score_manage.tk_select_box_score_department.get()
        if __score_manage.tk_select_box_score_course_name.current() == 0:
            __course_name = ''
        if __score_manage.tk_select_box_score_nature.current() == 0:
            __course_nature = ''
        if __score_manage.tk_select_box_score_department.current() == 0:
            __course_department = ''
        for _ in map(__score_manage.tk_table_stu_score.delete, __score_manage.tk_table_stu_score.get_children("")):
            pass
        __score_manage.tk_score_table_dataset = Dao.searchStudentScore(__course_name, __course_nature, __course_department)
        # 导入初始数据
        if __score_manage.tk_score_table_dataset.get("code") == 0 and __score_manage.tk_score_table_dataset.get("data"):
            for data in __score_manage.tk_score_table_dataset.get("data"):
                __score_manage.tk_table_stu_score.insert('', END, values=list(data.values()))
        __score_manage.tk_select_box_score_course_name.current(0)
        __score_manage.tk_select_box_score_nature.current(0)
        __score_manage.tk_select_box_score_department.current(0)
        print("搜索学生成绩!")

    def exportStuScore(self, evt):
        path = filedialog.askdirectory()
        try:
            book = openpyxl.Workbook()
            sheet = book.active
            fff = list(self.tk_tabs_content.tk_tabs_content_2.tk_table_stu_score_columns.keys())  # 获取表头信息
            sheet.append(fff)
            dataset = [list(data_item.values()) for data_item in
                       self.tk_tabs_content.tk_tabs_content_2.tk_score_table_dataset.get("data")]
            print(dataset)
            for i in dataset:
                sheet.append(i)
            book.save(f"{path}/student_score.xlsx")
            messagebox.showinfo("提示", "导出成功!")
        except Exception as e:
            messagebox.showinfo("提示", "导出失败!")
            print(e)
        print("导出学生成绩!", evt)

    def addStudentInfo(self, evt):
        self.addInfo = AddStudentPage.Win()
        self.addInfo.mainloop()
        print("<Button-1>事件未处理", evt)

    def deleteStudentInfo(self, evt):
        self.delete = DeleteStudentPage.Win()
        self.delete.mainloop()
        print("<Button-1>事件未处理", evt)

    def addStudentScore(self, evt):
        addScorePage = AddScorePage.Win()
        addScorePage.mainloop()

    def deleteStudentScore(self, evt):
        deleteScorePage = DeleteScorePage.Win()
        deleteScorePage.mainloop()
        print("删除学生成绩", evt)

    def updateTeacherPassword(self, evt):
        __original_pwd = self.tk_tabs_content.tk_tabs_content_4.tk_input_original_pwd.get()
        __new_pwd = self.tk_tabs_content.tk_tabs_content_4.tk_input_new_pwd.get()
        __confirm_pwd = self.tk_tabs_content.tk_tabs_content_4.tk_input_confirm_pwd.get()
        if __original_pwd == '' or __new_pwd == '' or __confirm_pwd == '':
            messagebox.showwarning("提示", "必填项未填写!")
            return
        if not re.match(r"^[0-9a-zA-Z~!@#$%^&*._?]{6,18}$", __original_pwd) \
                or not re.match(r"^[0-9a-zA-Z~!@#$%^&*._?]{6,18}$", __new_pwd) \
                or not re.match(r"^[0-9a-zA-Z~!@#$%^&*._?]{6,18}$", __confirm_pwd):
            messagebox.showwarning("提示", "密码格式应为6-18位数字、字母、特殊字符的组合!")
            return
        if __new_pwd != __confirm_pwd:
            messagebox.showwarning("提示", "两次密码输入不一致")
            return
        res = Dao.updatePassword(self.uid, __original_pwd, __new_pwd)
        messagebox.showinfo("提示", res.get("msg"))
        if res.get("code") == 0:
            self.destroy()
            login = Login.Win()
            login.mainloop()
        print("修改教师密码", evt)

    def addCourseInfo(self, evt):
        addCoursePage = AddCoursePage.Win()
        addCoursePage.mainloop()
        print("添加成绩!")

    def deleteCourseInfo(self, evt):
        deleteCoursePage = DeleteCoursePage.Win()
        deleteCoursePage.mainloop()
        print("删除课程!")

    def searchCourseInfo(self, evt):
        __course_manage = self.tk_tabs_content.tk_tabs_content_5
        __department = __course_manage.tk_select_box_course_department.get()
        __exammethod = __course_manage.tk_select_box_course_exam_method.get()
        if __course_manage.tk_select_box_course_department.current() == 0:
            __department = ''
        if __course_manage.tk_select_box_course_exam_method.current() == 0:
            __exammethod = ''
        for _ in map(__course_manage.tk_table_course_manage.delete, __course_manage.tk_table_course_manage.get_children("")):
            pass
        self.tk_tabs_content.tk_tabs_content_5.tk_course_table_dataset = Dao.searchCourses(__department, __exammethod)
        # 导入初始数据
        if self.tk_tabs_content.tk_tabs_content_5.tk_course_table_dataset.get("code") == 0 and self.tk_tabs_content.tk_tabs_content_5.tk_course_table_dataset.get("data"):
            for data in self.tk_tabs_content.tk_tabs_content_5.tk_course_table_dataset.get("data"):
                __course_manage.tk_table_course_manage.insert('', END, values=list(data.values()))
        __course_manage.tk_select_box_course_department.current(0)
        __course_manage.tk_select_box_course_exam_method.current(0)
        print("查询课程!")

    def updateCourseInfo(self, evt):
        __focus = self.tk_tabs_content.tk_tabs_content_5.tk_table_course_manage.focus()
        current_item = self.tk_tabs_content.tk_tabs_content_5.tk_table_course_manage.set(__focus)
        __cid = current_item.get("课程号")
        self.updateCoursePage = UpdateCoursePage.Win(__cid)
        self.updateCoursePage.mainloop()
        print("更新课程信息!")

    def exportCourseInfo(self, evt):
        path = filedialog.askdirectory()
        try:
            book = openpyxl.Workbook()
            sheet = book.active
            fff = list(self.tk_tabs_content.tk_tabs_content_5.tk_table_course_manage_columns.keys())  # 获取表头信息
            sheet.append(fff)
            dataset = [list(data_item.values()) for data_item in self.tk_tabs_content.tk_tabs_content_5.tk_course_table_dataset.get("data")]
            print(dataset)
            for i in dataset:
                sheet.append(i)
            book.save(path + "/course_info.xlsx")
            messagebox.showinfo("提示", "导出成功!")
        except Exception as e:
            messagebox.showinfo("提示", "导出失败!")
            print(e)

    def logout_user(self, evt):
        messagebox.showwarning('提示', '欢迎下次使用!')
        self.destroy()
        login = Login.Win()
        login.mainloop()

    def studentinfo_refresh(self, evt):
        # 删除原结点,加入新结点
        for _ in map(self.tk_tabs_content.tk_tabs_content_1.tk_table_student_query.delete,
                     self.tk_tabs_content.tk_tabs_content_1.tk_table_student_query.get_children("")):
            pass
        result = Dao.getAllStudents()
        if result.get("code") == 0:
            if result.get("data"):
                # print(result.get("data"))
                for values in result.get("data"):
                    self.tk_tabs_content.tk_tabs_content_1.tk_table_student_query.insert('', END,
                                                                                         values=list(values.values()))
            else:
                print("未查询到数据!")
        else:
            print("数据查询异常!")

    def studentinfo_export(self, evt):
        path = filedialog.askdirectory()
        try:
            book = openpyxl.Workbook()
            sheet = book.active
            fff = list(self.tk_tabs_content.tk_tabs_content_1.tk_table_student_manage_columns.keys())  # 获取表头信息
            sheet.append(fff)
            dataset = [list(data_item.values()) for data_item in
                       self.tk_tabs_content.tk_tabs_content_1.tk_student_table_dataset.get("data")]
            print(dataset)
            for i in dataset:
                sheet.append(i)
            book.save(path + "/student_info.xlsx")
            messagebox.showinfo("提示", "导出成功!")
        except Exception as e:
            messagebox.showinfo("提示", "导出失败!")
            print(e)

    def columnChart(self, evt):
        courseScoreAnalysis = CourseScoreAnalysis.Win()
        courseScoreAnalysis.mainloop()

    def paratacticColumnChart(self, evt):
        classGradeAnalysis = ClassGradeAnalysis.Win()
        classGradeAnalysis.mainloop()

    def pieChart(self, evt):
        comprehensivePerformanceEvaluation = ComprehensivePerformanceEvaluation.Win()
        comprehensivePerformanceEvaluation.mainloop()


    def __event_bind(self):
        self.protocol('WM_DELETE_WINDOW', self.logout)
        self.tk_tabs_content.tk_tabs_content_1.tk_table_student_query.bind('<<TreeviewSelect>>', self.updateStudentInfo)
        self.tk_tabs_content.tk_tabs_content_0.tk_button_tea_update.bind('<Button-1>', self.updateTeacherInfo)
        self.tk_tabs_content.tk_tabs_content_0.tk_button_tea_reset.bind('<Button-1>', self.resetTeacherInfo)
        self.tk_tabs_content.tk_tabs_content_1.tk_button_stu_search.bind('<Button-1>', self.searchStudentInfo)
        self.tk_tabs_content.tk_tabs_content_1.tk_button_addStudent.bind('<Button-1>', self.addStudentInfo)
        self.tk_tabs_content.tk_tabs_content_1.tk_button_delete_student.bind('<Button-1>', self.deleteStudentInfo)
        self.tk_tabs_content.tk_tabs_content_1.tk_button_stu_refresh.bind('<Button-1>', self.studentinfo_refresh)
        self.tk_tabs_content.tk_tabs_content_1.tk_button_studentinfo_export.bind('<Button-1>', self.studentinfo_export)
        self.tk_tabs_content.tk_tabs_content_2.tk_button_add_score.bind('<Button-1>', self.addStudentScore)
        self.tk_tabs_content.tk_tabs_content_2.tk_button_delete_score.bind('<Button-1>', self.deleteStudentScore)
        self.tk_tabs_content.tk_tabs_content_2.tk_table_stu_score.bind('<<TreeviewSelect>>', self.updateStudentScore)
        self.tk_tabs_content.tk_tabs_content_2.tk_button_stu_score_search.bind('<Button-1>', self.searchStuScore)
        self.tk_tabs_content.tk_tabs_content_2.tk_button_stu_score_export.bind('<Button-1>', self.exportStuScore)
        self.tk_tabs_content.tk_tabs_content_3.tk_button_columnChart.bind('<Button-1>', self.columnChart)
        self.tk_tabs_content.tk_tabs_content_3.tk_button_paratacticColumnChart.bind('<Button-1>', self.paratacticColumnChart)
        self.tk_tabs_content.tk_tabs_content_3.tk_button_pieChart.bind('<Button-1>', self.pieChart)

        self.tk_tabs_content.tk_tabs_content_4.tk_button_update_tea_pwd.bind('<Button-1>', self.updateTeacherPassword)
        self.tk_tabs_content.tk_tabs_content_5.tk_button_add_course.bind('<Button-1>', self.addCourseInfo)
        self.tk_tabs_content.tk_tabs_content_5.tk_button_delete_course.bind('<Button-1>', self.deleteCourseInfo)
        self.tk_tabs_content.tk_tabs_content_5.tk_button_course_search.bind('<Button-1>', self.searchCourseInfo)
        self.tk_tabs_content.tk_tabs_content_5.tk_button_course_export.bind('<Button-1>', self.exportCourseInfo)
        self.tk_tabs_content.tk_tabs_content_5.tk_table_course_manage.bind('<<TreeviewSelect>>', self.updateCourseInfo)
        self.tk_button_logout_user.bind('<Button-1>', self.logout_user)

学生端登录页面效果:

 

学生端——修改密码:

 学生端代码如下:

student.py:

from tkinter import *
from tkinter import messagebox, filedialog
from tkinter.ttk import *

import numpy as np
import openpyxl
from matplotlib import pyplot as plt

import Dao
import Login

global current_uid

class WinGUI(Tk):
    def __init__(self):
        super().__init__()
        self.__win()
        self.tk_label_title = self.__tk_label_title()
        self.tk_label_current_user = self.__tk_label_current_user()
        self.tk_tabs_content = Frame_content(self)
        self.tk_button_logout = self.__tk_button_logout()

    def __win(self):
        self.title("成绩查询")
        # 设置窗口大小、居中
        width = 1000
        height = 600
        screenwidth = self.winfo_screenwidth()
        screenheight = self.winfo_screenheight()
        geometry = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
        self.geometry(geometry)
        self.resizable(width=False, height=False)
        self.iconbitmap('logo.ico')

    def __tk_label_title(self):
        label = Label(self, text="学生成绩管理系统", anchor="center")
        label.place(x=0, y=0, width=800, height=100)
        return label

    def __tk_label_current_user(self):
        label = Label(self, text="当前用户:admin", anchor="center")
        label.place(x=800, y=70, width=150, height=30)
        return label

    def __tk_button_logout(self):
        btn = Button(self, text="退出")
        btn.place(x=950, y=70, width=50, height=30)
        return btn


class Frame_content(Notebook):
    def __init__(self, parent):
        super().__init__(parent)
        self.__frame()

    def __frame(self):
        self.tk_tabs_content_0 = Frame_content_0(self)
        self.add(self.tk_tabs_content_0, text="个人资料")

        self.tk_tabs_content_1 = Frame_content_1(self)
        self.add(self.tk_tabs_content_1, text="成绩查询")

        self.tk_tabs_content_3 = Frame_content_3(self)
        self.add(self.tk_tabs_content_3, text="修改密码")

        self.place(x=0, y=100, width=1000, height=500)


class Frame_content_0(Frame):
    def __init__(self, parent):
        super().__init__(parent)
        self.__frame()
        self.tk_label_stu_number = self.__tk_label_stu_number()
        self.tk_input_stu_number = self.__tk_input_stu_number()
        self.tk_label_stu_name = self.__tk_label_stu_name()
        self.tk_input_stu_name = self.__tk_input_stu_name()
        self.tk_label_stu_gender = self.__tk_label_stu_gender()
        self.tk_tk_select_stu_gender = self.__tk_select_stu_gender()
        self.tk_label_stu_identity = self.__tk_label_stu_identity()
        self.tk_input_stu_identity = self.__tk_input_stu_identity()
        self.tk_label_stu_email = self.__tk_label_stu_email()
        self.tk_input_stu_email = self.__tk_input_stu_email()
        self.tk_button_stu_update = self.__tk_button_stu_update()
        self.tk_button_stu_reset = self.__tk_button_stu_reset()

    def __frame(self):
        self.place(x=0, y=100, width=1000, height=500)

    def __tk_label_stu_number(self):
        label = Label(self, text="学号", anchor="e")
        label.place(x=360, y=40, width=100, height=30)
        return label

    def __tk_input_stu_number(self):
        self.student_number = StringVar(self)
        ipt = Entry(self, text=self.student_number)
        ipt.place(x=490, y=40, width=150, height=30)
        ipt.config(stat='disable')
        return ipt

    def __tk_label_stu_name(self):
        label = Label(self, text="姓名", anchor="e")
        label.place(x=360, y=110, width=100, height=30)
        return label

    def __tk_input_stu_name(self):
        self.student_name = StringVar(self)
        ipt = Entry(self, text=self.student_name)
        ipt.place(x=490, y=110, width=150, height=30)
        return ipt

    def __tk_label_stu_gender(self):
        label = Label(self, text="性别", anchor="e")
        label.place(x=360, y=180, width=100, height=30)
        return label

    def __tk_select_stu_gender(self):
        cb = Combobox(self, state='readonly')
        cb['values'] = ("", "")
        cb.place(x=490, y=180, width=150, height=30)
        return cb

    def __tk_label_stu_identity(self):
        label = Label(self, text="身份证号", anchor="e")
        label.place(x=360, y=250, width=100, height=30)
        return label

    def __tk_input_stu_identity(self):
        self.student_identify = StringVar(self)
        ipt = Entry(self, text=self.student_identify)
        ipt.place(x=490, y=250, width=150, height=30)
        return ipt

    def __tk_label_stu_email(self):
        label = Label(self, text="电子邮箱", anchor="e")
        label.place(x=360, y=320, width=100, height=30)
        return label

    def __tk_input_stu_email(self):
        self.student_email = StringVar(self)
        ipt = Entry(self, text=self.student_email)
        ipt.place(x=490, y=320, width=150, height=30)
        return ipt

    def __tk_button_stu_update(self):
        btn = Button(self, text="修改")
        btn.place(x=400, y=390, width=80, height=30)
        return btn

    def __tk_button_stu_reset(self):
        btn = Button(self, text="重置")
        btn.place(x=520, y=390, width=80, height=30)
        return btn


class Frame_content_1(Frame):
    def __init__(self, parent):
        super().__init__(parent)
        self.__frame()
        self.tk_button_analysis = self.__tk_button_analysis()
        self.tk_table_stu_score = self.__tk_table_stu_score()
        self.tk_select_box_course_nature = self.__tk_select_box_course_nature()
        self.tk_select_box_course_department = self.__tk_select_box_course_department()
        self.tk_select_box_exam_method = self.__tk_select_box_exam_method()
        self.tk_button_search = self.__tk_button_search()
        self.tk_button_export = self.__tk_button_export()

    def __frame(self):
        self.place(x=0, y=100, width=1000, height=500)

    def __tk_table_stu_score(self):
        # 表头字段 表头宽度
        self.tk_table_stu_score_columns = {"#": 50, "课程名称": 200, "课程性质": 150, "开课学院": 300, "考试方式": 100, "学分": 100, "成绩": 100}
        # 初始化表格 表格是基于Treeview,tkinter本身没有表格。show="headings" 为隐藏首列。
        tk_table = Treeview(self, show="headings", columns=list(self.tk_table_stu_score_columns))
        for text, width in self.tk_table_stu_score_columns.items():  # 批量设置列属性
            tk_table.heading(text, text=text, anchor='center')
            tk_table.column(text, anchor='center', width=width, stretch=False)  # stretch 不自动拉伸

        # 插入数据示例
        # self.tk_score_table_dataset = Dao.getScoreByUid(8888)
        # # 导入初始数据
        # if self.tk_score_table_dataset.get("code") == 0 and self.tk_score_table_dataset.get("data"):
        #     for data in self.tk_score_table_dataset.get("data"):
        #         tk_table.insert('', END, values=list(data.values()))

        tk_table.place(x=0, y=55, width=1000, height=420)
        return tk_table

    def __tk_button_analysis(self):
        btn = Button(self, text="分析")
        btn.place(x=65, y=10, width=75, height=30)
        return btn

    def __tk_select_box_course_nature(self):
        cb = Combobox(self, state="readonly")
        values = ["请选择课程性质"]
        for i in Dao.getDataDictByType("nature").get("data"):
            values.append(i.get("v"))
        cb['values'] = values
        cb.current(0)
        cb.place(x=180, y=10, width=150, height=30)
        return cb

    def __tk_select_box_course_department(self):
        cb = Combobox(self, state="readonly")
        values = ["请选择开课学院"]
        for i in Dao.getAllDepartments().get("data"):
            values.append(i.get("v"))
        cb['values'] = values
        cb.current(0)
        cb.place(x=370, y=10, width=150, height=30)
        return cb

    def __tk_select_box_exam_method(self):
        cb = Combobox(self, state="readonly")
        values = ["请选择考试方式"]
        for i in Dao.getDataDictByType("exammethod").get("data"):
            values.append(i.get("v"))
        cb['values'] = values
        cb.current(0)
        cb.place(x=560, y=10, width=150, height=30)
        return cb

    def __tk_button_search(self):
        btn = Button(self, text="搜索")
        btn.place(x=750, y=10, width=75, height=30)
        return btn

    def __tk_button_export(self):
        btn = Button(self, text="导出")
        btn.place(x=840, y=10, width=75, height=30)
        return btn


class Frame_content_3(Frame):
    def __init__(self, parent):
        super().__init__(parent)
        self.__frame()
        self.tk_label_original_password = self.__tk_label_original_password()
        self.tk_input_original_password = self.__tk_input_original_password()
        self.tk_label_new_password = self.__tk_label_new_password()
        self.tk_input_new_password = self.__tk_input_new_password()
        self.tk_label_confirm_password = self.__tk_label_confirm_password()
        self.tk_input_confirm_password = self.__tk_input_confirm_password()
        self.tk_button_update_stu_password = self.__tk_button_update_stu_password()

    def __frame(self):
        self.place(x=0, y=100, width=1000, height=500)

    def __tk_label_original_password(self):
        label = Label(self, text="原密码", anchor="e")
        label.place(x=360, y=40, width=100, height=30)
        return label

    def __tk_input_original_password(self):
        ipt = Entry(self, show='*')
        ipt.place(x=490, y=40, width=150, height=30)
        return ipt

    def __tk_label_new_password(self):
        label = Label(self, text="新密码", anchor="e")
        label.place(x=360, y=110, width=100, height=30)
        return label

    def __tk_input_new_password(self):
        ipt = Entry(self, show='*')
        ipt.place(x=490, y=110, width=150, height=30)
        return ipt

    def __tk_label_confirm_password(self):
        label = Label(self, text="确认密码", anchor="e")
        label.place(x=360, y=180, width=100, height=30)
        return label

    def __tk_input_confirm_password(self):
        ipt = Entry(self, show='*')
        ipt.place(x=490, y=180, width=150, height=30)
        return ipt

    def __tk_button_update_stu_password(self):
        btn = Button(self, text="修改")
        btn.place(x=460, y=250, width=100, height=30)
        return btn


class Win(WinGUI):
    def __init__(self, current_user):
        super().__init__()
        self.__event_bind()
        self.uid = current_user.get("uid")
        self.uclid = current_user.get("uclid")
        self.tk_label_current_user['text'] = "当前用户:" + current_user.get("uname")
        self.tk_tabs_content.tk_tabs_content_0.student_number.set(current_user.get("uid"))
        self.tk_tabs_content.tk_tabs_content_0.student_name.set(current_user.get("uname"))
        self.tk_tabs_content.tk_tabs_content_0.tk_tk_select_stu_gender.current(0 if current_user.get("ugender") == '' else 1)
        self.tk_tabs_content.tk_tabs_content_0.student_identify.set(current_user.get("uidentify"))
        self.tk_tabs_content.tk_tabs_content_0.student_email.set(current_user.get("uemail"))

        # 插入数据示例
        self.score_table_dataset = Dao.getScoreByUid(self.uid)
        # 导入初始数据
        if self.score_table_dataset.get("code") == 0 and self.score_table_dataset.get("data"):
            for data in self.score_table_dataset.get("data"):
                self.tk_tabs_content.tk_tabs_content_1.tk_table_stu_score.insert('', END, values=list(data.values()))

    def logout(self):
        messagebox.showwarning('提示', '欢迎下次使用!')
        self.destroy()
        login = Login.Win()
        login.mainloop()

    def updateStudentInfo(self, evt):
        __stu_name = self.tk_tabs_content.tk_tabs_content_0.tk_input_stu_name.get()
        __stu_gender = self.tk_tabs_content.tk_tabs_content_0.tk_tk_select_stu_gender.get()
        __stu_identify = self.tk_tabs_content.tk_tabs_content_0.tk_input_stu_identity.get()
        __stu_email = self.tk_tabs_content.tk_tabs_content_0.tk_input_stu_email.get()
        if not __stu_name or not __stu_gender or not __stu_identify or not __stu_email:
            messagebox.showinfo("提示", "必填项不能为空!")
            return
        if not re.match(r'^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$', __stu_identify):
            messagebox.showinfo("提示", "身份证格式不合法!")
            return
        if not re.match(r'^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$', __stu_email):
            messagebox.showinfo("提示", "电子邮箱格式不合法!")
            return
        res = Dao.updateUser(self.uid, __stu_name, __stu_gender, __stu_identify, self.uclid, __stu_email)
        messagebox.showinfo("提示", res.get("msg"))
        self.tk_label_current_user['text'] = "当前用户:" + __stu_name
        print("更新学生信息", evt)

    def stu_reset(self, evt):
        self.tk_tabs_content.tk_tabs_content_0.student_number.set(self.userInfo[0])
        self.tk_tabs_content.tk_tabs_content_0.student_name.set(self.userInfo[1])
        self.tk_tabs_content.tk_tabs_content_0.tk_tk_select_stu_gender.current(0 if self.userInfo[2] else 1)
        self.tk_tabs_content.tk_tabs_content_0.student_identify.set(self.userInfo[3])
        self.tk_tabs_content.tk_tabs_content_0.student_email.set(self.userInfo[5])

    def analysisStudentScore(self, evt):
        result = Dao.getScoreByUid(self.uid).get("data")
        plt.title('成绩统计图')
        # 设置x轴数据
        x = [i.get("cname") for i in result]
        # 每组数据n有3个类型
        total_width, n = 0.6, 3
        width = total_width / n
        y1 = [i.get("score") for i in result]
        y2 = [i.get("avg_score") for i in Dao.getAllCourseAvgScore(self.uid).get("data")]
        plt.bar(x, y1, color="b", width=width, label='我的成绩')
        plt.plot(x, y2, color="g", label='科目平均成绩')
        # x和y轴标题
        plt.xlabel("课程")
        plt.ylabel("分数")
        plt.legend(loc="best")
        plt.ylim((0, 100))
        # 设置纵轴起始,终止和间距
        my_y_ticks = np.arange(0, 100, 10)
        plt.yticks(my_y_ticks)
        plt.rcParams['font.sans-serif'] = ['SimHei']  # 支持中文显示
        plt.show()
        print("成绩分析图表绘制")

    def searchStudentScore(self, evt):
        __score_query = self.tk_tabs_content.tk_tabs_content_1
        __nature = __score_query.tk_select_box_course_nature.get()
        __department = __score_query.tk_select_box_course_department.get()
        __exammethod = __score_query.tk_select_box_exam_method.get()
        if __score_query.tk_select_box_course_nature.current() == 0:
            __nature = ''
        if __score_query.tk_select_box_course_department.current() == 0:
            __department = ''
        if __score_query.tk_select_box_exam_method.current() == 0:
            __exammethod = ''
        for _ in map(__score_query.tk_table_stu_score.delete, __score_query.tk_table_stu_score.get_children("")):
            pass
        self.score_table_dataset = Dao.getScoreByUid(self.uid, __nature, __department, __exammethod)
        # 导入初始数据
        if self.score_table_dataset.get("code") == 0 and self.score_table_dataset.get("data"):
            for data in self.score_table_dataset.get("data"):
                __score_query.tk_table_stu_score.insert('', END, values=list(data.values()))
        __score_query.tk_select_box_course_nature.current(0)
        __score_query.tk_select_box_course_department.current(0)
        __score_query.tk_select_box_exam_method.current(0)
        print(f"查询学生{self.uid}的成绩!")

    def exportStudentScore(self, evt):
        path = filedialog.askdirectory()
        try:
            book = openpyxl.Workbook()
            sheet = book.active
            fff = list(self.tk_tabs_content.tk_tabs_content_1.tk_table_stu_score_columns.keys())  # 获取表头信息
            sheet.append(fff)
            dataset = [list(data_item.values()) for data_item in
                       self.score_table_dataset.get("data")]
            print(dataset)
            for i in dataset:
                sheet.append(i)
            book.save(f"{path}/{self.uid}.xlsx")
            messagebox.showinfo("提示", "导出成功!")
        except Exception as e:
            messagebox.showinfo("提示", "导出失败!")
            print(e)
        print("<Button-1>事件未处理", evt)

    def updateStudentPassword(self, evt):
        __original_pwd = self.tk_tabs_content.tk_tabs_content_3.tk_input_original_password.get()
        __new_pwd = self.tk_tabs_content.tk_tabs_content_3.tk_input_new_password.get()
        __confirm_pwd = self.tk_tabs_content.tk_tabs_content_3.tk_input_confirm_password.get()
        if __original_pwd == '' or __new_pwd == '' or __confirm_pwd == '':
            messagebox.showwarning("提示", "必填项未填写!")
            return
        if not re.match(r"^[0-9a-zA-Z~!@#$%^&*._?]{6,18}$", __original_pwd) \
                or not re.match(r"^[0-9a-zA-Z~!@#$%^&*._?]{6,18}$", __new_pwd) \
                or not re.match(r"^[0-9a-zA-Z~!@#$%^&*._?]{6,18}$", __confirm_pwd):
            messagebox.showwarning("提示", "密码格式应为6-18位数字、字母、特殊字符的组合!")
            return
        if __new_pwd != __confirm_pwd:
            messagebox.showwarning("提示", "两次密码输入不一致")
            return
        res = Dao.updatePassword(self.uid, __original_pwd, __new_pwd)
        messagebox.showinfo("提示", res.get("msg"))
        if res.get("code") == 0:
            self.destroy()
            login = Login.Win()
            login.mainloop()
        print("修改密码", evt)

    def logout_user(self, evt):
        messagebox.showwarning('提示', '欢迎下次使用!')
        self.destroy()
        login = Login.Win()
        login.mainloop()

    def __event_bind(self):
        self.protocol('WM_DELETE_WINDOW', self.logout)
        self.tk_tabs_content.tk_tabs_content_0.tk_button_stu_update.bind('<Button-1>', self.updateStudentInfo)
        self.tk_tabs_content.tk_tabs_content_0.tk_button_stu_reset.bind('<Button-1>', self.stu_reset)
        self.tk_tabs_content.tk_tabs_content_1.tk_button_analysis.bind('<Button-1>', self.analysisStudentScore)
        self.tk_tabs_content.tk_tabs_content_1.tk_button_search.bind('<Button-1>', self.searchStudentScore)
        self.tk_tabs_content.tk_tabs_content_1.tk_button_export.bind('<Button-1>', self.exportStudentScore)
        self.tk_tabs_content.tk_tabs_content_3.tk_button_update_stu_password.bind('<Button-1>',
                                                                                  self.updateStudentPassword)
        self.tk_button_logout.bind('<Button-1>', self.logout_user)

数据库采用mysql 8.0,库名和表如下:

  Dao层代码如下:用于访问数据库,向数据库发送sql语句,完成成绩与科目等增删改查任务

Dao.py:

import pymysql


def getConnect():
    """
    获取数据库连接
    :return:
    """
    conn = pymysql.Connect(
        host='localhost',
        port=3306,
        user='#你的数据库用户名',
        password='#你的数据库密码',
        db='stu_sc_sys',
        charset='utf8',
        cursorclass=pymysql.cursors.DictCursor
    )
    cursor = conn.cursor()
    return conn, cursor


def getUserByIdAndPwd(username, password):
    conn, cursor = getConnect()
    sql = f"select uid, uname, ugender, uidentify, uclid, uemail, urole from user where uid='{username}' " \
          f"and upwd='{password}'"
    cursor.execute(sql)
    res = {
        "code": 0,
        "msg": "success",
        "data": cursor.fetchone()
    }
    cursor.close()
    conn.close()
    return res


def getUserInfoById(uid):
    conn, cursor = getConnect()
    sql = f"select uid, uname, ugender, uidentify, uclid, uemail, urole from user where uid='{uid}'"
    cursor.execute(sql)
    res = cursor.fetchone()
    cursor.close()
    conn.close()
    return res


def updatePassword(uid, origin_pwd, new_pwd):
    conn, cursor = getConnect()
    res = {
        "code": 1,
        "msg": "修改密码失败!"
    }
    if not getUserByIdAndPwd(uid, origin_pwd).get("data"):
        res = {
            "code": 1,
            "msg": "原密码不正确!"
        }
    else:
        sql = f"update user set upwd = '{new_pwd}' where uid = '{uid}'"
        try:
            cursor.execute(sql)
            conn.commit()
            res = {
                "code": 0,
                "msg": "修改成功!"
            }
        except Exception as e:
            conn.rollback()
            print(e)
    return res


def getScoreByUid(uid, nature='', department='', exam_method=''):
    """
    通过学号获取成绩
    :param uid:
    :param nature:
    :param department:
    :param exam_method:
    :return:
    """
    conn, cursor = getConnect()
    sql = f"select ROW_NUMBER() over () as id, uc.cname, c.cnature, c.cdepartment, c.cexammethod, c.ccredit, score " \
          f"from user_course uc inner join user u on uc.uid = u.uid inner join course c on uc.cname = c.cname " \
          f"where u.uid = '{uid}' and c.cnature like '%{nature}%' and " \
          f"c.cdepartment like '%{department}%' and c.cexammethod like '%{exam_method}%'"
    print(sql)
    cursor.execute(sql)
    res = {
        "code": 0,
        "msg": "success",
        "data": cursor.fetchall()
    }
    cursor.close()
    conn.close()
    return res


def getAllUsers():
    connection, cursor = getConnect()
    sql = 'select uid, uname, ugender, uidentify, uclid, uemail, upwd, urole from user'
    cursor.execute(sql)
    res = {
        "code": 0,
        "msg": "success",
        "data": cursor.fetchall()
    }
    cursor.close()
    connection.close()
    return res


def getAllStudents():
    connection, cursor = getConnect()
    sql = "select row_number() over () as id, uid, uname, ugender, uidentify, uclid, uemail from user where urole = 1"
    cursor.execute(sql)
    res = {
        "code": 0,
        "msg": "success",
        "data": cursor.fetchall()
    }
    cursor.close()
    connection.close()
    return res


def searchStudents(uname, ugender):
    """
    学生信息搜索
    :param uname:
    :param ugender:
    :return:
    """
    connection, cursor = getConnect()
    sql = f"select row_number() over () as id, uid, uname, ugender, uidentify, uclid, uemail, upwd, urole from user " \
          f"where urole = 1 and uname like '%{uname}%' and ugender like '%{ugender}%'"
    cursor.execute(sql)
    res = {
        "code": 0,
        "msg": "success",
        "data": cursor.fetchall()
    }
    cursor.close()
    connection.close()
    return res


def addStudent(uid, uname, ugender, uidentify, uclid, uemail):
    """
    添加一个学生信息,密码默认为123456
    :param uid:
    :param uname:
    :param ugender:
    :param uidentify:
    :param uclid:
    :param uemail:
    :return:
    """
    connection, cursor = getConnect()
    sql = f"insert into user(uid, uname, ugender, uidentify, uclid, uemail, upwd) values ('{uid}', '{uname}'" \
          f", '{ugender}', '{uidentify}', '{uclid}', '{uemail}', '123456') "
    res = {
        "code": 0,
        "msg": "添加成功!"
    }
    try:
        cursor.execute(sql)
        connection.commit()
    except Exception as e:
        res = {
            "code": 1,
            "msg": "添加失败!"
        }
        connection.rollback()
        print(e)
    cursor.close()
    connection.close()
    return res


def deleteUser(uid):
    """
    通过uid删除用户
    :param uid:
    :return:
    """
    connection, cursor = getConnect()
    sql = f"delete from user where uid = '{uid}'"
    res = {
        "code": 0,
        "msg": "删除成功!"
    }
    try:
        cursor.execute(sql)
        connection.commit()
    except Exception as e:
        res = {
            "code": 1,
            "msg": "删除失败!"
        }
        connection.rollback()
        print(e)
    cursor.close()
    connection.close()
    return res


def updateUser(uid, uname, ugender, uidentify, uclid, uemail):
    """
    通过uid更新用户信息
    :param uid:
    :param uname:
    :param ugender:
    :param uidentify:
    :param uclid:
    :param uemail:
    :return:
    """
    connection, cursor = getConnect()
    sql = f"update user set uname = '{uname}', ugender = '{ugender}', uidentify = '{uidentify}', uclid = '{uclid}'" \
          f", uemail ='{uemail}' where uid = '{uid}'"
    print(sql)
    res = {
        "code": 0,
        "msg": "修改成功!"
    }
    try:
        cursor.execute(sql)
        connection.commit()
    except Exception as e:
        res = {
            "code": 1,
            "msg": "修改失败!"
        }
        connection.rollback()
        print(e)
    cursor.close()
    connection.close()
    return res


def getAllCourses():
    """
    获取所有的课程信息
    :return:
    """
    connection, cursor = getConnect()
    sql = "select cid, cname, ccredit, cnature, cdepartment, cexammethod from course"
    cursor.execute(sql)
    res = {
        "code": 0,
        "msg": "success",
        "data": cursor.fetchall()
    }
    cursor.close()
    connection.close()
    return res


def getCourseByCid(cid):
    """
    获取cid的课程
    :return:
    """
    connection, cursor = getConnect()
    sql = f"select cid, cname, cnature, ccredit, cdepartment, cexammethod from course where cid = '{cid}'"
    cursor.execute(sql)
    res = {
        "code": 0,
        "msg": "success",
        "data": cursor.fetchall()
    }
    cursor.close()
    connection.close()
    return res


def getDataDictByType(dtype):
    """
    获取dtype类型的数据字典
    :param:
    :return:
    """
    connection, cursor = getConnect()
    sql = f"select d.ddtkey as k, d.ddtvalue as v from dictionary d where d.ddtype = '{dtype}'"
    cursor.execute(sql)
    res = {
        "code": 0,
        "msg": "success",
        "data": cursor.fetchall()
    }
    cursor.close()
    connection.close()
    return res


def getAllDepartments():
    """
    获取所有的学院
    :return:
    """
    connection, cursor = getConnect()
    sql = "select did as k, dname as v from department"
    cursor.execute(sql)
    res = {
        "code": 0,
        "msg": "success",
        "data": cursor.fetchall()
    }
    cursor.close()
    connection.close()
    return res


def getMaxStuNumber(s_num_prefix):
    """
    获取以s_num_prefix开头的最大学号
    :return:
    """
    connection, cursor = getConnect()
    sql = f"select MAX(uid) as max_id from user where uid like '{s_num_prefix}%'"
    cursor.execute(sql)
    res = {
        "code": 0,
        "msg": "success",
        "data": cursor.fetchall()
    }
    cursor.close()
    connection.close()
    return res


def addCourse(cname, nature, credit, department, exam_method):
    """
    添加课程
    :return:
    """
    connection, cursor = getConnect()
    sql = f"insert into course(cname, cnature, ccredit, cdepartment, cexammethod) VALUES ('{cname}', '{nature}'" \
          f", '{credit}', '{department}', '{exam_method}')"
    res = {
        "code": 0,
        "msg": "添加课程成功!"
    }
    try:
        cursor.execute(sql)
        connection.commit()
    except Exception as e:
        res = {
            "code": 1,
            "msg": "添加课程失败!"
        }
        connection.rollback()
        print(e)
    cursor.close()
    connection.close()
    return res


def deleteCourse(cid):
    """
    删除课程
    :return:
    """
    connection, cursor = getConnect()
    sql = f"delete from course where cid = {cid}"
    res = {
        "code": 0,
        "msg": "删除课程成功!"
    }
    try:
        cursor.execute(sql)
        connection.commit()
    except Exception as e:
        res = {
            "code": 1,
            "msg": "删除课程失败!"
        }
        connection.rollback()
        print(e)
    cursor.close()
    connection.close()
    return res


def searchCourses(department, exammethod):
    """
    搜索课程信息
    :param department:
    :param exammethod:
    :return:
    """
    connection, cursor = getConnect()
    sql = f"select cid, cname, ccredit, cnature, cdepartment, cexammethod from course " \
          f"where cdepartment like '%{department}%' and cexammethod like '%{exammethod}%'"
    cursor.execute(sql)
    res = {
        "code": 0,
        "msg": "success",
        "data": cursor.fetchall()
    }
    cursor.close()
    connection.close()
    return res


def updateCourseInfo(cid, cname, nature, credit, department, exammethod):
    """
    修改课程信息
    :param cid:
    :param cname:
    :param nature:
    :param credit:
    :param department:
    :param exammethod:
    :return:
    """
    connection, cursor = getConnect()
    sql = f"update course set cname = '{cname}', cnature = '{nature}', ccredit = '{credit}'" \
          f", cdepartment = '{department}', cexammethod = '{exammethod}' where cid = '{cid}'"
    res = {
        "code": 0,
        "msg": "修改课程成功!"
    }
    try:
        cursor.execute(sql)
        connection.commit()
    except Exception as e:
        res = {
            "code": 1,
            "msg": "更新课程失败!"
        }
        connection.rollback()
        print(e)
    cursor.close()
    connection.close()
    return res


def getScoreBandByCName(course_name):
    """
    获取课程名为course_name的各个分段的学生人数
    :param course_name:
    :return:
    """
    connection, cursor = getConnect()
    sql = f"select SUM(IF(score <= 100 and score >= 90, 1, 0)) as A, SUM(IF(score < 90 and score >= 80, 1, 0)) as B, " \
          f"SUM(IF(score < 80 and score >= 70, 1, 0)) as C, SUM(IF(score < 70 and score >= 60, 1, 0)) as D, " \
          f"SUM(IF(score < 60, 1, 0)) as E from user_course where cname = '{course_name}'"
    cursor.execute(sql)
    res = {
        "code": 0,
        "msg": "success",
        "data": cursor.fetchall()
    }
    cursor.close()
    connection.close()
    return res


def getMaxAndMinAndAvgScoreByCLid(class_id):
    """
    获取班级号为class_id的班级的各科最高分、最低分以及平均分
    :param class_id:
    :return:
    """
    connection, cursor = getConnect()
    sql = f"select uc.cname, MAX(score) as max_score, MIN(score) as min_score, AVG(score) as avg_score " \
          f"from user_course uc inner join user u on uc.uid = u.uid where u.uclid = '{class_id}' group by uc.cname"
    cursor.execute(sql)
    res = {
        "code": 0,
        "msg": "success",
        "data": cursor.fetchall()
    }
    cursor.close()
    connection.close()
    return res


def getOverallGradeLevelByCLid(class_id):
    """
    获取班级号为class_id的班级综合成绩等级各分段人数
    :param class_id:
    :return:
    """
    connection, cursor = getConnect()
    sql = f"select SUM(IF(avg_score >= 85 and avg_score <= 100, 1, 0)) as A, " \
          f"SUM(IF(avg_score >= 70 and avg_score < 85, 1, 0)) as B, " \
          f"SUM(IF(avg_score >= 60 and avg_score < 70, 1, 0)) as C, " \
          f"SUM(IF(avg_score < 60, 1, 0)) as D from (" \
          f"select AVG(score) as avg_score from user_course uc " \
          f"inner join user u on uc.uid = u.uid where u.uclid = '{class_id}' group by u.uid" \
          f") s"
    cursor.execute(sql)
    res = {
        "code": 0,
        "msg": "success",
        "data": cursor.fetchall()
    }
    cursor.close()
    connection.close()
    return res


def getAllClasses():
    """
    获取用户表中已存在的班级号
    :return:
    """
    connection, cursor = getConnect()
    sql = f"select distinct uclid from user where urole = 1"
    cursor.execute(sql)
    res = {
        "code": 0,
        "msg": "success",
        "data": cursor.fetchall()
    }
    cursor.close()
    connection.close()
    return res


def getAllCourseAvgScore(uid):
    """
    获取所有课程的平均分
    :return:
    """
    connection, cursor = getConnect()
    sql = f"select cname, AVG(score) as avg_score from user_course where cname in " \
          f"(select cname from user_course where uid = '{uid}') group by cname"
    cursor.execute(sql)
    res = {
        "code": 0,
        "msg": "success",
        "data": cursor.fetchall()
    }
    cursor.close()
    connection.close()
    return res


def searchStudentScore(course_name='', course_nature='', course_department=''):
    """
    搜索学生成绩
    :param course_name:
    :param course_nature:
    :param course_department:
    :return:
    """
    connection, cursor = getConnect()
    sql = f"select ROW_NUMBER() over () as id, u.uid, u.uname, uc.cname, c.cnature, c.cdepartment, c.cexammethod, " \
          f"c.ccredit, score from user_course uc inner join user u on uc.uid = u.uid inner join course c " \
          f"on uc.cname = c.cname where c.cname like '%{course_name}%' and " \
          f"c.cnature like '%{course_nature}%' and c.cdepartment like '%{course_department}%'"
    cursor.execute(sql)
    res = {
        "code": 0,
        "msg": "success",
        "data": cursor.fetchall()
    }
    cursor.close()
    connection.close()
    return res


def getScoreByUidAndCName(uid, course_name):
    """
    查找学号为uid课程为course_name的学生成绩
    :param uid:
    :param course_name:
    :return:
    """
    connection, cursor = getConnect()
    sql = f"select uid, cname, score from user_course where uid = '{uid}' and cname = '{course_name}'"
    cursor.execute(sql)
    res = {
        "code": 0,
        "msg": "success",
        "data": cursor.fetchall()
    }
    cursor.close()
    connection.close()
    return res


def addStudentScore(uid, course_name, score):
    connection, cursor = getConnect()
    if not cursor.execute(f"select uid from user where uid = '{uid}'"):
        return {
            "code": 1,
            "msg": "学号不存在!"
        }
    if cursor.execute(f"select 1 from user_course where uid = '{uid}' and cname = '{course_name}' limit 1"):
        return {
            "code": 1,
            "msg": f"该学生的{course_name}课程成绩已经存在!"
        }
    sql = f"insert into user_course(uid, cname, score) VALUES ('{uid}', '{course_name}', '{score}')"
    res = {
        "code": 0,
        "msg": "添加成绩成功!"
    }
    try:
        cursor.execute(sql)
        connection.commit()
    except Exception as e:
        res = {
            "code": 1,
            "msg": "添加成绩失败!"
        }
        connection.rollback()
        print(e)
    cursor.close()
    connection.close()
    return res


def deleteStudentScore(uid, course_name):
    connection, cursor = getConnect()
    if not cursor.execute(f"select uid from user where uid = '{uid}'"):
        return {
            "code": 1,
            "msg": "学号不存在!"
        }
    sql = f"delete from user_course where uid = '{uid}' and cname = '{course_name}'"
    res = {
        "code": 0,
        "msg": "删除成绩成功!"
    }
    try:
        code = cursor.execute(sql)
        connection.commit()
        if code == 0:
            res = {
                "code": 0,
                "msg": f"该学生的{course_name}课程成绩不存在!"
            }
    except Exception as e:
        res = {
            "code": 1,
            "msg": "删除成绩失败!"
        }
        connection.rollback()
        print(e)
    cursor.close()
    connection.close()
    return res


def updateStudentScore(uid, course_name, score):
    connection, cursor = getConnect()
    sql = f"update user_course set score = '{score}' where uid = '{uid}' and cname = '{course_name}'"
    res = {
        "code": 0,
        "msg": "修改成绩成功!"
    }
    try:
        cursor.execute(sql)
        connection.commit()
    except Exception as e:
        res = {
            "code": 1,
            "msg": "修改成绩失败!"
        }
        connection.rollback()
        print(e)
    cursor.close()
    connection.close()
    return res

 

 

 

 

 

 

from tkinter import *from tkinter import messagebox, filedialogfrom tkinter.ttk import *
import openpyxl as openpyxl
import AddCoursePageimport AddScorePageimport ClassGradeAnalysisimport ComprehensivePerformanceEvaluationimport CourseScoreAnalysisimport Daoimport DeleteCoursePageimport DeleteScorePageimport Loginimport UpdateCoursePage
import AddStudentPageimport DeleteStudentPageimport UpdateScorePageimport UpdateStudentPage
import numpy as npimport matplotlib.pyplot as plt
class WinGUI(Tk):    def __init__(self):        super().__init__()        self.__win()        self.tk_label_title = self.__tk_label_title()        self.tk_label_current_user = self.__tk_label_current_user()        self.tk_tabs_content = Frame_content(self)        self.tk_button_logout_user = self.__tk_button_logout_user()
    def __win(self):        self.title("教师端")        # 设置窗口大小、居中        width = 1000        height = 600        screenwidth = self.winfo_screenwidth()        screenheight = self.winfo_screenheight()        geometry = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)        self.geometry(geometry)        self.resizable(width=False, height=False)        self.iconbitmap('logo.ico')
    def __tk_label_title(self):        label = Label(self, text="学生成绩管理系统", anchor="center")        label.place(x=0, y=0, width=800, height=100)        return label
    def __tk_label_current_user(self):        label = Label(self, text="当前用户:admin", anchor="center")        label.place(x=800, y=70, width=150, height=30)        return label
    def __tk_button_logout_user(self):        btn = Button(self, text="退出")        btn.place(x=950, y=70, width=50, height=30)        return btn

class Frame_content(Notebook):    def __init__(self, parent):        super().__init__(parent)        self.__frame()
    def __frame(self):        self.tk_tabs_content_0 = Frame_content_0(self)        self.add(self.tk_tabs_content_0, text="个人资料")
        self.tk_tabs_content_1 = Frame_content_1(self)        self.add(self.tk_tabs_content_1, text="学生查询")
        self.tk_tabs_content_2 = Frame_content_2(self)        self.add(self.tk_tabs_content_2, text="成绩查询")
        self.tk_tabs_content_3 = Frame_content_3(self)        self.add(self.tk_tabs_content_3, text="成绩分析")
        self.tk_tabs_content_4 = Frame_content_4(self)        self.add(self.tk_tabs_content_4, text="修改密码")
        self.tk_tabs_content_5 = Frame_content_5(self)        self.add(self.tk_tabs_content_5, text="课程管理")
        self.place(x=0, y=100, width=1000, height=500)

class Frame_content_0(Frame):    def __init__(self, parent):        super().__init__(parent)        self.__frame()        self.tk_label_tea_number = self.__tk_label_tea_number()        self.tk_input_tea_number = self.__tk_input_tea_number()        self.tk_label_tea_name = self.__tk_label_tea_name()        self.tk_input_tea_name = self.__tk_input_tea_name()        self.tk_label_tea_gender = self.__tk_label_tea_gender()        self.tk_select_tea_gender = self.__tk_select_tea_gender()        self.tk_label_tea_identity = self.__tk_label_tea_identity()        self.tk_input_tea_identity = self.__tk_input_tea_identity()        self.tk_label_tea_email = self.__tk_label_tea_email()        self.tk_input_tea_email = self.__tk_input_tea_email()        self.tk_button_tea_update = self.__tk_button_tea_update()        self.tk_button_tea_reset = self.__tk_button_tea_reset()
    def __frame(self):        self.place(x=0, y=100, width=1000, height=500)
    def __tk_label_tea_number(self):        label = Label(self, text="工号", anchor="e")        label.place(x=360, y=40, width=100, height=30)        return label
    def __tk_input_tea_number(self):        self.tea_number = StringVar(self)        ipt = Entry(self,  text=self.tea_number)        ipt.place(x=490, y=40, width=150, height=30)        ipt.config(stat='disable')        return ipt
    def __tk_label_tea_name(self):        label = Label(self, text="姓名", anchor="e")        label.place(x=360, y=110, width=100, height=30)        return label
    def __tk_input_tea_name(self):        self.tea_name = StringVar(self)        ipt = Entry(self,  text=self.tea_name)        ipt.place(x=490, y=110, width=150, height=30)        return ipt
    def __tk_label_tea_gender(self):        label = Label(self, text="性别", anchor="e")        label.place(x=360, y=180, width=100, height=30)        return label
    def __tk_select_tea_gender(self):        cb = Combobox(self, state='readonly')        cb['values'] = ("男", "女")        cb.place(x=490, y=180, width=150, height=30)        return cb
    def __tk_label_tea_identity(self):        label = Label(self, text="身份证号", anchor="e")        label.place(x=360, y=250, width=100, height=30)        return label
    def __tk_input_tea_identity(self):        self.tea_identify = StringVar(self)        ipt = Entry(self,  text=self.tea_identify)        ipt.place(x=490, y=250, width=150, height=30)        return ipt
    def __tk_label_tea_email(self):        label = Label(self, text="电子邮箱", anchor="e")        label.place(x=360, y=320, width=100, height=30)        return label
    def __tk_input_tea_email(self):        self.tea_email = StringVar(self)        ipt = Entry(self,  text=self.tea_email)        ipt.place(x=490, y=320, width=150, height=30)        return ipt
    def __tk_button_tea_update(self):        btn = Button(self, text="修改")        btn.place(x=400, y=390, width=80, height=30)        return btn
    def __tk_button_tea_reset(self):        btn = Button(self, text="重置")        btn.place(x=520, y=390, width=80, height=30)        return btn

class Frame_content_1(Frame):    def __init__(self, parent):        super().__init__(parent)        self.__frame()        self.tk_table_student_query = self.__tk_table_student_query()        self.tk_input_stu_name = self.__tk_input_stu_name()        self.tk_select_box_stu_gender = self.__tk_select_box_stu_gender()        self.tk_button_stu_search = self.__tk_button_stu_search()        self.tk_button_addStudent = self.__tk_button_addStudent()        self.tk_button_delete_student = self.__tk_button_delete_student()        self.tk_button_stu_refresh = self.__tk_button_stu_refresh()        self.tk_button_studentinfo_export = self.__tk_button_studentinfo_export()
    def __frame(self):        self.place(x=0, y=100, width=1000, height=500)
    def __tk_table_student_query(self):        # 表头字段 表头宽度        self.tk_table_student_manage_columns = {"ID": 50, "学号": 100, "姓名": 150, '性别': 100, '身份证号': 300, '班级': 100, '邮箱': 200}        # 初始化表格 表格是基于Treeview,tkinter本身没有表格。show="headings" 为隐藏首列。        tk_table = Treeview(self, show="headings", columns=list(self.tk_table_student_manage_columns))        for text, width in self.tk_table_student_manage_columns.items():  # 批量设置列属性            tk_table.heading(text, text=text, anchor='center')            tk_table.column(text, anchor='center', width=width, stretch=False)  # stretch 不自动拉伸
        # 插入数据示例              #        # # 导入初始数据        self.tk_student_table_dataset = Dao.getAllStudents()        if self.tk_student_table_dataset.get("code") == 0:            if self.tk_student_table_dataset.get("data"):                print(self.tk_student_table_dataset.get("data"))                for values in self.tk_student_table_dataset.get("data"):                    tk_table.insert('', END, values=list(values.values()))            else:                print("未查询到数据!")        else:            print("数据查询异常!")
        tk_table.place(x=0, y=60, width=1000, height=415)        return tk_table
    def __tk_input_stu_name(self):        ipt = Entry(self)        ipt.place(x=360, y=10, width=150, height=30)        return ipt
    def __tk_select_box_stu_gender(self):        cb = Combobox(self, state="readonly")        cb['values'] = ("请选择性别", "男", "女")        cb.place(x=540, y=10, width=150, height=30)        cb.current(0)        return cb
    def __tk_button_stu_search(self):        btn = Button(self, text="搜索")        btn.place(x=720, y=10, width=70, height=30)        return btn
    def __tk_button_stu_refresh(self):        btn = Button(self, text="刷新")        btn.place(x=820, y=10, width=70, height=30)        return btn
    def __tk_button_addStudent(self):        btn = Button(self, text="添加学生")        btn.place(x=50, y=10, width=100, height=30)        return btn
    def __tk_button_delete_student(self):        btn = Button(self, text="删除学生")        btn.place(x=180, y=10, width=100, height=30)        return btn
    def __tk_button_studentinfo_export(self):        btn = Button(self, text="导出")        btn.place(x=920, y=10, width=50, height=30)        return btn

class Frame_content_2(Frame):    def __init__(self, parent):        super().__init__(parent)        self.__frame()        self.tk_table_stu_score = self.__tk_table_stu_score()        self.tk_button_add_score = self.__tk_button_add_score()        self.tk_button_delete_score = self.__tk_button_delete_score()        self.tk_select_box_score_course_name = self.__tk_select_box_score_course_name()        self.tk_select_box_score_nature = self.__tk_select_box_score_nature()        self.tk_select_box_score_department = self.__tk_select_box_score_department()        self.tk_button_stu_score_search = self.__tk_button_stu_score_search()        self.tk_button_stu_score_export = self.__tk_button_stu_score_export()
    def __frame(self):        self.place(x=0, y=100, width=1000, height=500)
    def __tk_table_stu_score(self):        # 表头字段 表头宽度        self.tk_table_stu_score_columns = {"#": 50, "学号": 70, "姓名": 80, "课程名称": 200, "课程性质": 100, "开课学院": 270, "考试方式": 80, "学分": 50, "成绩": 100}        # 初始化表格 表格是基于Treeview,tkinter本身没有表格。show="headings" 为隐藏首列。        tk_table = Treeview(self, show="headings", columns=list(self.tk_table_stu_score_columns))        for text, width in self.tk_table_stu_score_columns.items():  # 批量设置列属性            tk_table.heading(text, text=text, anchor='center')            tk_table.column(text, anchor='center', width=width, stretch=False)  # stretch 不自动拉伸
        # 插入数据示例        self.tk_score_table_dataset = Dao.searchStudentScore()        # 导入初始数据        if self.tk_score_table_dataset.get("code") == 0 and self.tk_score_table_dataset.get("data"):            for data in self.tk_score_table_dataset.get("data"):                tk_table.insert('', END, values=list(data.values()))
        tk_table.place(x=0, y=60, width=1000, height=415)        return tk_table
    def __tk_button_add_score(self):        btn = Button(self, text="添加成绩")        btn.place(x=50, y=10, width=100, height=30)        return btn
    def __tk_button_delete_score(self):        btn = Button(self, text="删除成绩")        btn.place(x=170, y=10, width=100, height=30)        return btn
    def __tk_select_box_score_course_name(self):        cb = Combobox(self, state="readonly")        values = ["请选择课程名称"]        for i in Dao.getAllCourses().get("data"):            values.append(i.get("cname"))        cb['values'] = values        cb.current(0)        cb.place(x=290, y=10, width=150, height=30)        return cb
    def __tk_select_box_score_nature(self):        cb = Combobox(self, state="readonly")        values = ["请选择课程性质"]        for i in Dao.getDataDictByType("nature").get("data"):            values.append(i.get("v"))        cb['values'] = values        cb.current(0)        cb.place(x=460, y=10, width=150, height=30)        return cb
    def __tk_select_box_score_department(self):        cb = Combobox(self, state="readonly")        values = ["请选择开课学院"]        for i in Dao.getAllDepartments().get("data"):            values.append(i.get("v"))        cb['values'] = values        cb.current(0)        cb.place(x=630, y=10, width=150, height=30)        return cb
    def __tk_button_stu_score_search(self):        btn = Button(self, text="搜索")        btn.place(x=800, y=10, width=70, height=30)        return btn
    def __tk_button_stu_score_export(self):        btn = Button(self, text="导出")        btn.place(x=890, y=10, width=70, height=30)        return btn

class Frame_content_3(Frame):    def __init__(self, parent):        super().__init__(parent)        self.__frame()        self.tk_button_pieChart = self.__tk_button_pieChart()        self.tk_button_columnChart = self.__tk_button_columnChart()        self.tk_button_paratacticColumnChart = self.__tk_button_paratacticColumnChart()
    def __frame(self):        self.place(x=0, y=100, width=1000, height=500)
    def __tk_button_columnChart(self):        btn = Button(self, text="课程成绩分析")        btn.place(x=80, y=50, width=150, height=70)        return btn
    def __tk_button_paratacticColumnChart(self):        btn = Button(self, text="班级成绩分析")        btn.place(x=420, y=50, width=150, height=70)        return btn
    def __tk_button_pieChart(self):        btn = Button(self, text="综合成绩评定")        btn.place(x=760, y=50, width=150, height=70)        return btn

class Frame_content_4(Frame):    def __init__(self, parent):        super().__init__(parent)        self.__frame()        self.tk_label_original_pwd = self.__tk_label_original_pwd()        self.tk_input_original_pwd = self.__tk_input_original_pwd()        self.tk_label_new_pwd = self.__tk_label_new_pwd()        self.tk_input_new_pwd = self.__tk_input_new_pwd()        self.tk_label_confirm_pwd = self.__tk_label_confirm_pwd()        self.tk_input_confirm_pwd = self.__tk_input_confirm_pwd()        self.tk_button_update_tea_pwd = self.__tk_button_update_tea_pwd()
    def __frame(self):        self.place(x=0, y=100, width=1000, height=500)
    def __tk_label_original_pwd(self):        label = Label(self, text="原密码", anchor="e")        label.place(x=360, y=40, width=100, height=30)        return label
    def __tk_input_original_pwd(self):        ipt = Entry(self, show='*')        ipt.place(x=490, y=40, width=150, height=30)        return ipt
    def __tk_label_new_pwd(self):        label = Label(self, text="新密码", anchor="e")        label.place(x=360, y=110, width=100, height=30)        return label
    def __tk_input_new_pwd(self):        ipt = Entry(self, show='*')        ipt.place(x=490, y=110, width=150, height=30)        return ipt
    def __tk_label_confirm_pwd(self):        label = Label(self, text="确认密码", anchor="e")        label.place(x=360, y=180, width=100, height=30)        return label
    def __tk_input_confirm_pwd(self):        ipt = Entry(self, show='*')        ipt.place(x=490, y=180, width=150, height=30)        return ipt
    def __tk_button_update_tea_pwd(self):        btn = Button(self, text="修改")        btn.place(x=450, y=260, width=100, height=30)        return btn

class Frame_content_5(Frame):    def __init__(self, parent):        super().__init__(parent)        self.__frame()        self.tk_table_course_manage = self.__tk_table_course_manage()        self.tk_button_add_course = self.__tk_button_add_course()        self.tk_button_delete_course = self.__tk_button_delete_course()        self.tk_select_box_course_department = self.__tk_select_box_course_department()        self.tk_select_box_course_exam_method = self.__tk_select_box_course_exam_method()        self.tk_button_course_search = self.__tk_button_course_search()        self.tk_button_course_export = self.__tk_button_course_export()
    def __frame(self):        self.place(x=0, y=100, width=1000, height=500)
    def __tk_table_course_manage(self):        # 表头字段 表头宽度        self.tk_table_course_manage_columns = {"课程号": 100, "课程名称": 200, "学分": 100, "课程性质": 200, "开课学院": 300, "考试方式": 100}        # 初始化表格 表格是基于Treeview,tkinter本身没有表格。show="headings" 为隐藏首列。        tk_table = Treeview(self, show="headings", columns=list(self.tk_table_course_manage_columns))        for text, width in self.tk_table_course_manage_columns.items():  # 批量设置列属性            tk_table.heading(text, text=text, anchor='center')            tk_table.column(text, anchor='center', width=width, stretch=False)  # stretch 不自动拉伸
        # 插入数据示例        self.tk_course_table_dataset = Dao.getAllCourses()        # 导入初始数据        if self.tk_course_table_dataset.get("code") == 0 and self.tk_course_table_dataset.get("data"):            for data in self.tk_course_table_dataset.get("data"):                tk_table.insert('', END, values=list(data.values()))
        tk_table.place(x=0, y=60, width=1000, height=415)        return tk_table
    def __tk_button_add_course(self):        btn = Button(self, text="添加课程")        btn.place(x=50, y=10, width=100, height=30)        return btn
    def __tk_button_delete_course(self):        btn = Button(self, text="删除课程")        btn.place(x=180, y=10, width=100, height=30)        return btn
    def __tk_select_box_course_department(self):        cb = Combobox(self, state="readonly")        values = ["请选择开课学院"]        for i in Dao.getAllDepartments().get("data"):            values.append(i.get("v"))        cb['values'] = values        cb.current(0)        cb.place(x=310, y=10, width=150, height=30)        return cb
    def __tk_select_box_course_exam_method(self):        cb = Combobox(self, state="readonly")        values = ["请选择考试方式"]        for i in Dao.getDataDictByType("exammethod").get("data"):            values.append(i.get("v"))        cb['values'] = values        cb.current(0)        cb.place(x=490, y=10, width=150, height=30)        return cb
    def __tk_button_course_search(self):        btn = Button(self, text="搜索")        btn.place(x=670, y=10, width=100, height=30)        return btn
    def __tk_button_course_export(self):        btn = Button(self, text="导出")        btn.place(x=800, y=10, width=100, height=30)        return btn

class Win(WinGUI):    def __init__(self, current_user):        super().__init__()        self.__event_bind()        self.current_user = current_user        self.uid = current_user.get("uid")        self.tk_label_current_user['text'] = "当前用户:" + current_user.get("uname")        self.tk_tabs_content.tk_tabs_content_0.tea_number.set(current_user.get("uid"))        self.tk_tabs_content.tk_tabs_content_0.tea_name.set(current_user.get("uname"))        self.tk_tabs_content.tk_tabs_content_0.tk_select_tea_gender.current(0 if current_user.get("ugender") == '男' else 1)        self.tk_tabs_content.tk_tabs_content_0.tea_identify.set(current_user.get("uidentify"))        self.tk_tabs_content.tk_tabs_content_0.tea_email.set(current_user.get("uemail"))
    def logout(self):        try:            self.updateStudent.destroy()            self.addInfo.destroy()            self.delete.destroy()        except Exception as e:            print(e)        messagebox.showwarning('提示', '欢迎下次使用!')        self.destroy()        login = Login.Win()        login.mainloop()
    def updateStudentInfo(self, evt):        current_focus = self.tk_tabs_content.tk_tabs_content_1.tk_table_student_query.focus()        current_studentinfo = self.tk_tabs_content.tk_tabs_content_1.tk_table_student_query.set(current_focus)        current_uid = current_studentinfo.get('学号')        self.updateStudent = UpdateStudentPage.Win(current_uid)        self.updateStudent.mainloop()        print("<<TreeviewSelect>>事件未处理", evt)
    def updateTeacherInfo(self, evt):        __tea_name = self.tk_tabs_content.tk_tabs_content_0.tk_input_tea_name.get()        __tea_gender = self.tk_tabs_content.tk_tabs_content_0.tk_select_tea_gender.get()        __tea_identify = self.tk_tabs_content.tk_tabs_content_0.tk_input_tea_identity.get()        __tea_email = self.tk_tabs_content.tk_tabs_content_0.tk_input_tea_email.get()        if not __tea_name or not __tea_gender or not __tea_identify or not __tea_email:            messagebox.showinfo("提示", "必填项不能为空!")            return        if not re.match(r'^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$',                        __tea_identify):            messagebox.showinfo("提示", "身份证格式不合法!")            return        if not re.match(r'^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$', __tea_email):            messagebox.showinfo("提示", "电子邮箱格式不合法!")            return        res = Dao.updateUser(self.uid, __tea_name, __tea_gender, __tea_identify, 0, __tea_email)        messagebox.showinfo("提示", res.get("msg"))        self.tk_label_current_user['text'] = "当前用户:" + __tea_name        print("更新教师信息", evt)
    def resetTeacherInfo(self, evt):        self.tk_tabs_content.tk_tabs_content_0.tea_name.set(self.current_user.get("uname"))        self.tk_tabs_content.tk_tabs_content_0.tk_select_tea_gender.current(0 if self.current_user.get("ugender") == '男' else 1)        self.tk_tabs_content.tk_tabs_content_0.tea_identify.set(self.current_user.get("uidentify"))        self.tk_tabs_content.tk_tabs_content_0.tea_email.set(self.current_user.get("uemail"))        print("重置教师信息", evt)
    def searchStudentInfo(self, evt):        for _ in map(self.tk_tabs_content.tk_tabs_content_1.tk_table_student_query.delete,                     self.tk_tabs_content.tk_tabs_content_1.tk_table_student_query.get_children("")):            pass        value = self.tk_tabs_content.tk_tabs_content_1.tk_input_stu_name.get()        num = self.tk_tabs_content.tk_tabs_content_1.tk_select_box_stu_gender.get()        print(num, value)        if num == '请选择性别':            result = Dao.searchStudents(value, '')        else:            result = Dao.searchStudents(value, num)        if result.get("code") == 0:            if result.get("data"):                # print(result.get("data"))                for values in result.get("data"):                    self.tk_tabs_content.tk_tabs_content_1.tk_table_student_query.insert('', END, values=list(values.values()))            else:                print("未查询到数据!")        else:            print("数据查询异常!")        print("搜索学生信息", evt)
    def updateStudentScore(self, evt):        current_item = self.tk_tabs_content.tk_tabs_content_2.tk_table_stu_score.set(self.tk_tabs_content.tk_tabs_content_2.tk_table_stu_score.focus())        data = {            "uid": current_item.get("学号"),            "cname": current_item.get("课程名称"),            "score": current_item.get("成绩")        }        updateScorePage = UpdateScorePage.Win(data)        updateScorePage.mainloop()        print("修改学生课程成绩", evt)
    def searchStuScore(self, evt):        __score_manage = self.tk_tabs_content.tk_tabs_content_2        __course_name = __score_manage.tk_select_box_score_course_name.get()        __course_nature = __score_manage.tk_select_box_score_nature.get()        __course_department = __score_manage.tk_select_box_score_department.get()        if __score_manage.tk_select_box_score_course_name.current() == 0:            __course_name = ''        if __score_manage.tk_select_box_score_nature.current() == 0:            __course_nature = ''        if __score_manage.tk_select_box_score_department.current() == 0:            __course_department = ''        for _ in map(__score_manage.tk_table_stu_score.delete, __score_manage.tk_table_stu_score.get_children("")):            pass        __score_manage.tk_score_table_dataset = Dao.searchStudentScore(__course_name, __course_nature, __course_department)        # 导入初始数据        if __score_manage.tk_score_table_dataset.get("code") == 0 and __score_manage.tk_score_table_dataset.get("data"):            for data in __score_manage.tk_score_table_dataset.get("data"):                __score_manage.tk_table_stu_score.insert('', END, values=list(data.values()))        __score_manage.tk_select_box_score_course_name.current(0)        __score_manage.tk_select_box_score_nature.current(0)        __score_manage.tk_select_box_score_department.current(0)        print("搜索学生成绩!")
    def exportStuScore(self, evt):        path = filedialog.askdirectory()        try:            book = openpyxl.Workbook()            sheet = book.active            fff = list(self.tk_tabs_content.tk_tabs_content_2.tk_table_stu_score_columns.keys())  # 获取表头信息            sheet.append(fff)            dataset = [list(data_item.values()) for data_item in                       self.tk_tabs_content.tk_tabs_content_2.tk_score_table_dataset.get("data")]            print(dataset)            for i in dataset:                sheet.append(i)            book.save(f"{path}/student_score.xlsx")            messagebox.showinfo("提示", "导出成功!")        except Exception as e:            messagebox.showinfo("提示", "导出失败!")            print(e)        print("导出学生成绩!", evt)
    def addStudentInfo(self, evt):        self.addInfo = AddStudentPage.Win()        self.addInfo.mainloop()        print("<Button-1>事件未处理", evt)
    def deleteStudentInfo(self, evt):        self.delete = DeleteStudentPage.Win()        self.delete.mainloop()        print("<Button-1>事件未处理", evt)
    def addStudentScore(self, evt):        addScorePage = AddScorePage.Win()        addScorePage.mainloop()
    def deleteStudentScore(self, evt):        deleteScorePage = DeleteScorePage.Win()        deleteScorePage.mainloop()        print("删除学生成绩", evt)
    def updateTeacherPassword(self, evt):        __original_pwd = self.tk_tabs_content.tk_tabs_content_4.tk_input_original_pwd.get()        __new_pwd = self.tk_tabs_content.tk_tabs_content_4.tk_input_new_pwd.get()        __confirm_pwd = self.tk_tabs_content.tk_tabs_content_4.tk_input_confirm_pwd.get()        if __original_pwd == '' or __new_pwd == '' or __confirm_pwd == '':            messagebox.showwarning("提示", "必填项未填写!")            return        if not re.match(r"^[0-9a-zA-Z~!@#$%^&*._?]{6,18}$", __original_pwd) \                or not re.match(r"^[0-9a-zA-Z~!@#$%^&*._?]{6,18}$", __new_pwd) \                or not re.match(r"^[0-9a-zA-Z~!@#$%^&*._?]{6,18}$", __confirm_pwd):            messagebox.showwarning("提示", "密码格式应为6-18位数字、字母、特殊字符的组合!")            return        if __new_pwd != __confirm_pwd:            messagebox.showwarning("提示", "两次密码输入不一致")            return        res = Dao.updatePassword(self.uid, __original_pwd, __new_pwd)        messagebox.showinfo("提示", res.get("msg"))        if res.get("code") == 0:            self.destroy()            login = Login.Win()            login.mainloop()        print("修改教师密码", evt)
    def addCourseInfo(self, evt):        addCoursePage = AddCoursePage.Win()        addCoursePage.mainloop()        print("添加成绩!")
    def deleteCourseInfo(self, evt):        deleteCoursePage = DeleteCoursePage.Win()        deleteCoursePage.mainloop()        print("删除课程!")
    def searchCourseInfo(self, evt):        __course_manage = self.tk_tabs_content.tk_tabs_content_5        __department = __course_manage.tk_select_box_course_department.get()        __exammethod = __course_manage.tk_select_box_course_exam_method.get()        if __course_manage.tk_select_box_course_department.current() == 0:            __department = ''        if __course_manage.tk_select_box_course_exam_method.current() == 0:            __exammethod = ''        for _ in map(__course_manage.tk_table_course_manage.delete, __course_manage.tk_table_course_manage.get_children("")):            pass        self.tk_tabs_content.tk_tabs_content_5.tk_course_table_dataset = Dao.searchCourses(__department, __exammethod)        # 导入初始数据        if self.tk_tabs_content.tk_tabs_content_5.tk_course_table_dataset.get("code") == 0 and self.tk_tabs_content.tk_tabs_content_5.tk_course_table_dataset.get("data"):            for data in self.tk_tabs_content.tk_tabs_content_5.tk_course_table_dataset.get("data"):                __course_manage.tk_table_course_manage.insert('', END, values=list(data.values()))        __course_manage.tk_select_box_course_department.current(0)        __course_manage.tk_select_box_course_exam_method.current(0)        print("查询课程!")
    def updateCourseInfo(self, evt):        __focus = self.tk_tabs_content.tk_tabs_content_5.tk_table_course_manage.focus()        current_item = self.tk_tabs_content.tk_tabs_content_5.tk_table_course_manage.set(__focus)        __cid = current_item.get("课程号")        self.updateCoursePage = UpdateCoursePage.Win(__cid)        self.updateCoursePage.mainloop()        print("更新课程信息!")
    def exportCourseInfo(self, evt):        path = filedialog.askdirectory()        try:            book = openpyxl.Workbook()            sheet = book.active            fff = list(self.tk_tabs_content.tk_tabs_content_5.tk_table_course_manage_columns.keys())  # 获取表头信息            sheet.append(fff)            dataset = [list(data_item.values()) for data_item in self.tk_tabs_content.tk_tabs_content_5.tk_course_table_dataset.get("data")]            print(dataset)            for i in dataset:                sheet.append(i)            book.save(path + "/course_info.xlsx")            messagebox.showinfo("提示", "导出成功!")        except Exception as e:            messagebox.showinfo("提示", "导出失败!")            print(e)
    def logout_user(self, evt):        messagebox.showwarning('提示', '欢迎下次使用!')        self.destroy()        login = Login.Win()        login.mainloop()
    def studentinfo_refresh(self, evt):        # 删除原结点,加入新结点        for _ in map(self.tk_tabs_content.tk_tabs_content_1.tk_table_student_query.delete,                     self.tk_tabs_content.tk_tabs_content_1.tk_table_student_query.get_children("")):            pass        result = Dao.getAllStudents()        if result.get("code") == 0:            if result.get("data"):                # print(result.get("data"))                for values in result.get("data"):                    self.tk_tabs_content.tk_tabs_content_1.tk_table_student_query.insert('', END,                                                                                         values=list(values.values()))            else:                print("未查询到数据!")        else:            print("数据查询异常!")
    def studentinfo_export(self, evt):        path = filedialog.askdirectory()        try:            book = openpyxl.Workbook()            sheet = book.active            fff = list(self.tk_tabs_content.tk_tabs_content_1.tk_table_student_manage_columns.keys())  # 获取表头信息            sheet.append(fff)            dataset = [list(data_item.values()) for data_item in                       self.tk_tabs_content.tk_tabs_content_1.tk_student_table_dataset.get("data")]            print(dataset)            for i in dataset:                sheet.append(i)            book.save(path + "/student_info.xlsx")            messagebox.showinfo("提示", "导出成功!")        except Exception as e:            messagebox.showinfo("提示", "导出失败!")            print(e)
    def columnChart(self, evt):        courseScoreAnalysis = CourseScoreAnalysis.Win()        courseScoreAnalysis.mainloop()
    def paratacticColumnChart(self, evt):        classGradeAnalysis = ClassGradeAnalysis.Win()        classGradeAnalysis.mainloop()
    def pieChart(self, evt):        comprehensivePerformanceEvaluation = ComprehensivePerformanceEvaluation.Win()        comprehensivePerformanceEvaluation.mainloop()

    def __event_bind(self):        self.protocol('WM_DELETE_WINDOW', self.logout)        self.tk_tabs_content.tk_tabs_content_1.tk_table_student_query.bind('<<TreeviewSelect>>', self.updateStudentInfo)        self.tk_tabs_content.tk_tabs_content_0.tk_button_tea_update.bind('<Button-1>', self.updateTeacherInfo)        self.tk_tabs_content.tk_tabs_content_0.tk_button_tea_reset.bind('<Button-1>', self.resetTeacherInfo)        self.tk_tabs_content.tk_tabs_content_1.tk_button_stu_search.bind('<Button-1>', self.searchStudentInfo)        self.tk_tabs_content.tk_tabs_content_1.tk_button_addStudent.bind('<Button-1>', self.addStudentInfo)        self.tk_tabs_content.tk_tabs_content_1.tk_button_delete_student.bind('<Button-1>', self.deleteStudentInfo)        self.tk_tabs_content.tk_tabs_content_1.tk_button_stu_refresh.bind('<Button-1>', self.studentinfo_refresh)        self.tk_tabs_content.tk_tabs_content_1.tk_button_studentinfo_export.bind('<Button-1>', self.studentinfo_export)        self.tk_tabs_content.tk_tabs_content_2.tk_button_add_score.bind('<Button-1>', self.addStudentScore)        self.tk_tabs_content.tk_tabs_content_2.tk_button_delete_score.bind('<Button-1>', self.deleteStudentScore)        self.tk_tabs_content.tk_tabs_content_2.tk_table_stu_score.bind('<<TreeviewSelect>>', self.updateStudentScore)        self.tk_tabs_content.tk_tabs_content_2.tk_button_stu_score_search.bind('<Button-1>', self.searchStuScore)        self.tk_tabs_content.tk_tabs_content_2.tk_button_stu_score_export.bind('<Button-1>', self.exportStuScore)        self.tk_tabs_content.tk_tabs_content_3.tk_button_columnChart.bind('<Button-1>', self.columnChart)        self.tk_tabs_content.tk_tabs_content_3.tk_button_paratacticColumnChart.bind('<Button-1>', self.paratacticColumnChart)        self.tk_tabs_content.tk_tabs_content_3.tk_button_pieChart.bind('<Button-1>', self.pieChart)
        self.tk_tabs_content.tk_tabs_content_4.tk_button_update_tea_pwd.bind('<Button-1>', self.updateTeacherPassword)        self.tk_tabs_content.tk_tabs_content_5.tk_button_add_course.bind('<Button-1>', self.addCourseInfo)        self.tk_tabs_content.tk_tabs_content_5.tk_button_delete_course.bind('<Button-1>', self.deleteCourseInfo)        self.tk_tabs_content.tk_tabs_content_5.tk_button_course_search.bind('<Button-1>', self.searchCourseInfo)        self.tk_tabs_content.tk_tabs_content_5.tk_button_course_export.bind('<Button-1>', self.exportCourseInfo)        self.tk_tabs_content.tk_tabs_content_5.tk_table_course_manage.bind('<<TreeviewSelect>>', self.updateCourseInfo)        self.tk_button_logout_user.bind('<Button-1>', self.logout_user)