4. 主界面
效果
程序设计
import tkinter as tk import numpy as np import register import selUser import login import findSno import updPwd import findCno import db class MainWin(): def __init__(self): self.root3 = tk.Tk() self.root3.title("成绩分析") self.screenwidth = self.root3.winfo_screenwidth() self.screenheight = self.root3.winfo_screenheight() self.root3.geometry('%dx%d+%d+%d' % (500, 300, (self.screenwidth - 500) / 2, (self.screenheight - 300) / 2)) menu1 = tk.Menu(self.root3) menu1_2 = tk.Menu(menu1, tearoff=False) # 创建二级菜单 menu1.add_cascade(label="用户管理", menu=menu1_2) # 创建级联菜单 menu1_2.add_command(label='用户注册', command=self.adduser) menu1_2.add_command(label='密码修改', command=self.updPwd) menu1_2.add_command(label='查询用户信息', command=self.seluser) menu1_2.add_command(label='重新登录', command=self.loginuser) menu1.add_command(label='退出系统', command=self.root3.quit) self.root3.config(menu=menu1_2) self.root3.config(menu=menu1) # 显示菜单 self.finds = tk.Label(self.root3, text='成绩分析', font=("黑体", 20)) self.finds.place(x=180, y=30) self.student_sno = tk.Label(self.root3, text='请输入要查询成绩的学生学号:', font=("黑体", 12)) self.student_sno.place(x=50, y=100) self.entry_sno = tk.Entry(self.root3) self.entry_sno.place(x=280, y=100) self.find_sgrade = tk.Button(self.root3, text='查询', font=("黑体", 15), command=self.findsno) self.find_sgrade.place(x=200, y=130) self.student_cno = tk.Label(self.root3, text='请输入要查询成绩的课程代号:', font=("黑体", 12)) self.student_cno.place(x=50, y=200) self.entry_cno = tk.Entry(self.root3) self.entry_cno.place(x=280, y=200) self.find_cgrade = tk.Button(self.root3, text='查询', font=("黑体", 15), command=self.findcno) self.find_cgrade.place(x=200, y=230) self.root3.mainloop() def adduser(self): self.root3.destroy() register.Register() def loginuser(self): self.root3.destroy() login.Login() def seluser(self): selUser.SelUser() def updPwd(self): self.root3.destroy() updPwd.UpdPWD() def findsno(self): fsno = self.entry_sno.get() snos = np.array(db.query("select sno from sc"))[:, 0] if fsno.strip() not in snos: tk.messagebox.showerror("警告", "该用户不存在成绩!") return False else: db.Findsno = fsno findSno.Manage() def findcno(self): fcno = self.entry_cno.get() cnos = np.array(db.query("select grade from sc where cno=%s and grade is not null", fcno)) print(cnos) if len(cnos) == 0: tk.messagebox.showerror("警告", "该课程不存在成绩!") return False else: db.Findcno = fcno findCno.Manage()
程序分析
这是一个使用Tkinter编写的成绩分析界面程序。程序主要分为两部分,即界面设计和响应事件处理。
在界面设计部分,代码使用了Tkinter的各种控件,包括Label、Entry、Button等,用于显示和接收用户输入信息,同时也添加了菜单栏,用于管理用户信息。具体设计如下:
- 创建一个顶级窗口root3,并设置标题和窗口大小。
- 创建一个菜单栏menu1,并添加一个级联菜单menu1_2,包含用户注册、密码修改、查询用户信息和重新登录功能。
- 添加一个Label控件,用于显示“成绩分析”。
- 添加两个Label控件和两个Entry控件,用于接收学号和课程代码。
- 添加两个Button控件,分别用于查询学生成绩和查询课程成绩。
在响应事件处理部分,代码使用了各种函数来实现各种功能:
- adduser()函数用于处理用户注册操作,当用户按下“用户注册”按钮时,关闭当前成绩分析窗口(root3),并跳转到注册界面。
- loginuser()函数用于处理重新登录操作,当用户按下“重新登录”按钮时,关闭当前成绩分析窗口(root3),并返回到登录界面。
- seluser()函数用于处理查询用户信息操作,当用户按下“查询用户信息”按钮时,弹出窗口,显示用户信息。
- updPwd()函数用于处理密码修改操作,当用户按下“密码修改”按钮时,关闭当前成绩分析窗口(root3),并跳转到密码修改界面。
- findsno()函数用于处理查询学生成绩操作,获取用户输入的学号,按照先验证学号是否存在于数据库中,如果存在则将学号传递至查询学生成绩的界面,如果不存在则给出相应提示。
- findcno()函数用于处理查询课程成绩操作,获取用户输入的课程代码,按照先验证课程代码是否存在于数据库中,如果存在则将课程代码传递至查询课程成绩的界面,如果不存在则给出相应提示。
程序中还调用了db.py。
5. 查询信息
效果
程序设计
import tkinter as tk import tkinter.ttk as ttk import db class SelUser(): def __init__(self): self.root4 = tk.Tk() # 创建根窗口 self.root4.title("查询用户信息") # 设置窗口标题 self.screenwidth = self.root4.winfo_screenwidth() self.screenheight = self.root4.winfo_screenheight() self.root4.geometry('%dx%d+%d+%d' % (400, 250, (self.screenwidth - 400) / 2, (self.screenheight - 250) / 2)) self.create_gui() # 调用窗口组件函数 self.root4.mainloop() # 让程序继续执行,直到窗口关闭 def create_gui(self): # 定义图形用户界面函数 self.create_top_right_labelframe() # 查询条件组件设置 self.create_records_treeview() # 查询结果树形菜单组件设置 def create_top_right_labelframe(self): # 查询条件组件界面 labelframe1 = tk.LabelFrame(self.root4, text='用户信息', width=400) # 标签框架组件 labelframe1.grid(row=0, column=1, sticky='ew', padx=8, pady=8) tk.Label(labelframe1, text=' 账号:').grid(row=1, column=1, sticky='w', pady=2) # 账号标签 self.namefield = tk.Entry(labelframe1) # 账号输入框 self.namefield.grid(row=1, column=2, sticky='w', padx=5, pady=2) tk.Label(labelframe1, text=' 密码:').grid(row=2, column=1, sticky='w', pady=2) self.numfield = tk.Entry(labelframe1) self.numfield.grid(row=2, column=2, sticky='w', padx=5, pady=2) tk.Button(labelframe1, text='查询', command=self.seluser).grid(row=3, column=1, sticky='e', padx=5, pady=2) def create_records_treeview(self): # 显示记录信息 treeview_columns = ['userId', 'userName', 'userPwd'] self.record_treeview = ttk.Treeview(self.root4, show='headings', height=5, columns=treeview_columns) self.record_treeview.grid(row=4, column=0, columnspan=3) self.record_treeview.heading('userId', text='序号') self.record_treeview.heading('userName', text='用户名') self.record_treeview.heading('userPwd', text='密码') # , anchor='center' self.record_treeview.column('userId', width=100) self.record_treeview.column('userName', width=120) self.record_treeview.column('userPwd', width=220) def seluser(self): username3 = self.namefield.get() userpwd3 = self.numfield.get() if username3.strip() == "" or userpwd3.strip() == "": tk.messagebox.showerror("警告", "用户名或密码不能为空") return False else: rs, row = db.query2( "select * from users where username like '%" + username3 + "%' and passwords like '%" + userpwd3 + "%'") if row == 0: tk.messagebox.showerror("警告", "该用户名或密码不存在") return False else: for i in range(row): self.record_treeview.insert("", 'end', values=rs[i])
程序分析
这段代码是一个查询用户信息的窗口,使用了tkinter来创建GUI界面,并且使用了MySQL数据库进行数据查询。其中包括如下函数:
- __init__(self)
- 创建根窗口
- 设置窗口标题
- 获取屏幕宽高
- 调用create_gui()创建窗口组件
- 执行mainloop()让程序继续执行
- create_gui(self)
- 调用create_top_right_labelframe()创建查询条件组件
- 调用create_records_treeview()创建查询结果树形菜单组件
- create_top_right_labelframe(self)
- 创建标签框架组件
- 创建账号和密码标签
- 创建输入框和查询按钮
- 将查询按钮与seluser()函数绑定
- create_records_treeview(self)
- 创建树形菜单组件
- 设置树形菜单展示的列和标题
- 设置树形菜单每列的宽度
- seluser(self)
- 获取输入的账号和密码信息
- 判断输入是否为空,如果为空则弹窗警告
- 如果输入不为空则调用db.query2函数进行数据库查询
- 如果查询结果为空则弹窗警告
- 如果查询结果不为空则遍历查询结果并添加到树形菜单中
总结:这段代码主要是使用了tkinter和MySQL实现了查询用户信息的功能,并且使用了GUI界面进行操作和显示。
6. 修改密码
效果
程序设计
import tkinter as tk import tkinter.messagebox import db import mainWin class UpdPWD(): def __init__(self): self.aa = db.Username self.root6 = tk.Tk() self.screenwidth = self.root6.winfo_screenwidth() self.screenheight = self.root6.winfo_screenheight() self.root6.geometry('%dx%d+%d+%d' % (400, 200, (self.screenwidth - 400) / 2, (self.screenheight - 200) / 2)) self.root6.title("密码修改窗口") self.namelabel = tk.Label(self.root6, text='账号:', font=("黑体", 15)) self.namelabel.place(x=80, y=20) self.nametxt = tk.Entry(self.root6) self.nametxt.place(x=140, y=22) self.nametxt.insert(0, self.aa) self.labelpwd1 = tk.Label(self.root6, text='密码:', font=("黑体", 15)) self.labelpwd1.place(x=80, y=60) self.pwd1 = tk.Entry(self.root6) self.pwd1.place(x=140, y=62) self.labelpwd2 = tk.Label(self.root6, text='确认密码:', font=("黑体", 12)) self.labelpwd2.place(x=60, y=100) self.pwd2 = tk.Entry(self.root6) self.pwd2.place(x=140, y=102) self.button = tk.Button(self.root6, text="确定", font=("黑体", 15), command=self.updpwd) self.button.place(x=100, y=140) self.button2 = tk.Button(self.root6, text="主窗口", font=("黑体", 15), command=self.returnwin) self.button2.place(x=200,y=140) self.root6.mainloop() def updpwd(self): bb = self.pwd1.get() aa = self.aa print(aa) print(bb) rs = db.update2("update tb_user set username='" + bb + "' where passwords='" + aa + "'") print(rs) if rs > 0: tk.messagebox.showinfo("提示消息", "密码修改成功") else: tk.messagebox.showinfo("提示消息", "修改失败") self.pwd1.delete(0) self.pwd2.delete(0) def returnwin(self): self.root6.destroy() mainWin.MainWin()
程序分析
这是一个基于tkinter GUI库实现的密码修改窗口类(UpdPWD)。
首先,在类的构造函数中,该类初始化了界面窗口(self.root6),设置窗口标题和尺寸,以及创建并放置标签(Label)和输入框(Entry)。
然后,在 updpwd() 方法中,该类获取输入框中的新密码,并将其通过执行数据库更新操作(update2()),更新到原先密码对应的账号上,如果更新成功,则弹出 “密码修改成功” 的提示框,否则弹出 “修改失败” 的提示框,并清空密码输入框。
最后,在 returnwin() 方法中,该类关闭当前窗口,并打开主窗口(MainWin)。
总的来说,该类实现了密码修改窗口的基本功能,并通过调用数据库进行数据更新操作,并添加了错误提示信息和返回主窗口按钮。同时,该类的代码结构比较清晰,易于理解和维护。
7. 成绩分析
7.1 通过学号查询成绩
效果
程序设计
import tkinter as tk import matplotlib.pyplot as plt import numpy as np import matplotlib import db from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from matplotlib.figure import Figure plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False class Manage(): def __init__(self): matplotlib.use("TkAgg") self.root7 = tk.Tk() self.root7.title("学生成绩分析") self.screenwidth = self.root7.winfo_screenwidth() self.screenheight = self.root7.winfo_screenheight() self.root7.geometry('%dx%d+%d+%d' % (400, 350, (self.screenwidth - 400) / 2, (self.screenheight - 350) / 2)) f = Figure(figsize=(5, 4), dpi=85) a = f.add_subplot(111) find_name = db.Findsno data = db.query("select * from sc where %s=sno and grade is not null", find_name) x = np.array(data)[:, 1] y = np.array(data)[:, 2].astype(int) a.plot(x, y, marker='o', color='red', label='成绩') for m, n in zip(x, y): a.text(m, n, n, ha='center', va='bottom', fontsize=12) a.set_title("学生%s成绩情况折线图" % find_name, fontsize=12) a.set_yticks(np.arange(0, 105, 10)) a.set_xlabel("课程号", fontsize=12) a.set_ylabel("成绩", fontsize=12) a.legend(loc='lower right') canvas = FigureCanvasTkAgg(f, self.root7) canvas.draw() canvas.get_tk_widget().pack() canvas._tkcanvas.pack() self.root7.mainloop()
程序分析
这段代码是一个可视化学生成绩的窗口,使用了tkinter和matplotlib库来创建GUI界面和绘制折线图。具体分析如下:
- init(self)
- 创建根窗口
- 设置窗口标题
- 获取屏幕宽高
- 创建Figure对象,设置图形大小和分辨率
- 调用add_subplot()方法创建子图
- 调用db.Findsno获取学生学号,调用db.query查询该学生的成绩
- 将查询结果存储在numpy数组中
- 调用plot()方法绘制折线图
- 调用text()方法给每个点添加标签
- 调用设置子图标题、x轴、y轴标签和图例等属性
- 调用FigureCanvasTkAgg()方法将图形绘制到GUI界面上
- canvas.draw()
- 绘制图形
- canvas.get_tk_widget().pack()
- 显示GUI界面
- canvas._tkcanvas.pack()
- 将tkinter版的canvas嵌入GUI中
总结:这段代码主要是使用了matplotlib库来绘制折线图,并且使用了tkinter库创建GUI界面,实现了可视化学生成绩的功能,方便用户查看分析。
7.2 通过课程号查询成绩
效果
程序设计
import tkinter as tk import matplotlib.pyplot as plt import numpy as np import matplotlib import db from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from matplotlib.figure import Figure plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False class Manage(): def __init__(self): matplotlib.use("TkAgg") self.root5 = tk.Tk() self.root5.title("课程成绩分析") self.screenwidth = self.root5.winfo_screenwidth() self.screenheight = self.root5.winfo_screenheight() self.root5.geometry('%dx%d+%d+%d' % (400, 350, (self.screenwidth - 400) / 2, (self.screenheight - 350) / 2)) f = Figure(figsize=(5, 4), dpi=85) a = f.add_subplot(111) find_name = db.Findcno data = db.query("select * from sc where %s=cno and grade is not null", find_name) x = np.array(data)[:, 0] y = np.array(data)[:, 2].astype(int) a.plot(x, y, marker='o', color='blue', label='成绩') for m, n in zip(x, y): a.text(m, n, n, ha='center', va='bottom', fontsize=12) a.set_title("课程%s成绩情况折线图" % find_name, fontsize=12) a.set_yticks(np.arange(0, 105, 10)) a.set_xlabel("课程号", fontsize=12) a.set_ylabel("成绩", fontsize=12) a.legend(loc='lower right') canvas = FigureCanvasTkAgg(f, self.root5) canvas.draw() canvas.get_tk_widget().pack() canvas._tkcanvas.pack() self.root5.mainloop()
程序分析
这段代码是一个可视化课程成绩的窗口,与可视化学生成绩的窗口十分类似。具体分析如下:
- init(self)
- 创建根窗口
- 设置窗口标题
- 获取屏幕宽高
- 创建Figure对象,设置图形大小和分辨率
- 调用add_subplot()方法创建子图
- 调用db.Findcno获取课程号,调用db.query查询该课程的成绩
- 将查询结果存储在numpy数组中
- 调用plot()方法绘制折线图
- 调用text()方法给每个点添加标签
- 调用设置子图标题、x轴、y轴标签和图例等属性
- 调用FigureCanvasTkAgg()方法将图形绘制到GUI界面上
- canvas.draw()
- 绘制图形
- canvas.get_tk_widget().pack()
- 显示GUI界面
- canvas._tkcanvas.pack()
- 将tkinter版的canvas嵌入GUI中
总结:这段代码与可视化学生成绩的窗口十分类似,主要是使用了matplotlib库来绘制折线图,并且使用了tkinter库创建GUI界面,实现了可视化课程成绩的功能,方便用户查看分析。
7. 主函数
import login #主函数 if __name__ == "__main__": login.Login()
尾声
该学生成绩管理系统需要有一些Python程序设计、Python数据分析以及MySQL数据库的基础,相信大家在亲自完成这个项目之后,一定收获不小吧!