Python成绩管理系统 - 使用Tkinter和Pandas
import tkinter as tk from tkinter import filedialog, messagebox import pandas as pd import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
class GradeManagementSystem: def init(self, master): self.master = master self.master.title('成绩管理系统') self.master.geometry('800x600')
self.data = pd.DataFrame(columns=['班级','姓名','学号','语文','数学','英语','总分','平均分'])
self.current_class = None
tk.Label(self.master, text='成绩管理系统', font=('Arial', 16)).pack(pady=10)
tk.Button(self.master, text='加载数据', command=self.load_data).pack(pady=10)
tk.Button(self.master, text='录入成绩', command=self.add_grade).pack(pady=10)
tk.Button(self.master, text='查询成绩', command=self.search_grade).pack(pady=10)
tk.Button(self.master, text='排序成绩', command=self.sort_grade).pack(pady=10)
tk.Button(self.master, text='查找学生', command=self.find_student).pack(pady=10)
tk.Button(self.master, text='导出数据', command=self.export_data).pack(pady=10)
tk.Button(self.master, text='生成图表', command=self.plot_scores).pack(pady=10)
self.grade_table = tk.Frame(self.master)
self.grade_table.pack(pady=20)
def load_data(self):
file_path = filedialog.askopenfilename(title='选择文件')
if file_path.endswith('.xlsx') or file_path.endswith('.xls'):
self.data = pd.read_excel(file_path)
messagebox.showinfo(title='提示', message='数据加载成功')
self.current_class = None
self.grade_table()
else:
messagebox.showerror(title='错误', message='请选择Excel文件')
def add_grade(self):
add_window = tk.Toplevel(self.master)
add_window.title('录入成绩')
add_window.geometry('300x250')
tk.Label(add_window, text='请选择班级:').pack(pady=10)
class_var = tk.StringVar(add_window)
class_var.set(self.current_class)
class_menu = tk.OptionMenu(add_window, class_var, *self.data['班级'].unique())
class_menu.pack()
tk.Label(add_window, text='请输入姓名:').pack(pady=10)
name_entry = tk.Entry(add_window)
name_entry.pack()
tk.Label(add_window, text='请输入学号:').pack(pady=10)
id_entry = tk.Entry(add_window)
id_entry.pack()
tk.Label(add_window, text='请输入语文成绩:').pack(pady=10)
chinese_entry = tk.Entry(add_window)
chinese_entry.pack()
tk.Label(add_window, text='请输入数学成绩:').pack(pady=10)
math_entry = tk.Entry(add_window)
math_entry.pack()
tk.Label(add_window, text='请输入英语成绩:').pack(pady=10)
english_entry = tk.Entry(add_window)
english_entry.pack()
def add():
class_name = class_var.get()
name = name_entry.get()
student_id = id_entry.get()
chinese = chinese_entry.get()
math = math_entry.get()
english = english_entry.get()
if class_name and name and student_id and chinese and math and english:
try:
chinese = float(chinese)
math = float(math)
english = float(english)
total = chinese + math + english
average = total / 3
new_data = pd.DataFrame([[class_name, name, student_id, chinese, math, english, total, average]],
columns=['班级','姓名','学号','语文','数学','英语','总分','平均分'])
self.data = pd.concat([self.data, new_data], ignore_index=True)
messagebox.showinfo(title='提示', message='成绩录入成功')
self.grade_table()
except ValueError:
messagebox.showerror(title='错误', message='成绩必须为数字')
else:
messagebox.showerror(title='错误', message='所有字段均为必填项')
tk.Button(add_window, text='录入', command=add).pack(pady=10)
def search_grade(self):
search_window = tk.Toplevel(self.master)
search_window.title('查询成绩')
search_window.geometry('300x200')
tk.Label(search_window, text='请输入学号或姓名:').pack(pady=10)
search_entry = tk.Entry(search_window)
search_entry.pack()
def search():
keyword = search_entry.get()
if keyword:
result = self.data.loc[(self.data['姓名'] == keyword) | (self.data['学号'] == keyword)]
if len(result) > 0:
messagebox.showinfo(title='查询结果', message=result.to_string(index=False))
else:
messagebox.showerror(title='错误', message='未找到学生信息')
else:
messagebox.showerror(title='错误', message='请输入关键词')
tk.Button(search_window, text='查询', command=search).pack(pady=10)
def sort_grade(self):
sort_window = tk.Toplevel(self.master)
sort_window.title('排序成绩')
sort_window.geometry('300x200')
tk.Label(sort_window, text='请选择排序方式:').pack(pady=10)
sort_var = tk.StringVar(sort_window, '总分')
tk.Radiobutton(sort_window, text='总分', variable=sort_var, value='总分').pack()
tk.Radiobutton(sort_window, text='平均分', variable=sort_var, value='平均分').pack()
tk.Label(sort_window, text='请选择班级(可选):').pack(pady=10)
class_var = tk.StringVar(sort_window)
class_menu = tk.OptionMenu(sort_window, class_var, *['所有班级']+list(self.data['班级'].unique()))
class_menu.pack()
def sort():
sort_col = sort_var.get()
class_name = class_var.get()
if sort_col:
if class_name != '所有班级':
self.current_class = class_name
self.grade_table()
data = self.data.loc[self.data['班级'] == class_name]
else:
self.current_class = None
self.grade_table()
data = self.data
data.sort_values(by=sort_col, ascending=False, inplace=True)
messagebox.showinfo(title='提示', message='排序成功')
self.grade_table()
else:
messagebox.showerror(title='错误', message='请选择排序方式')
tk.Button(sort_window, text='排序', command=sort).pack(pady=10)
def find_student(self):
find_window = tk.Toplevel(self.master)
find_window.title('查找学生')
find_window.geometry('300x200')
tk.Label(find_window, text='请输入学号:').pack(pady=10)
find_entry = tk.Entry(find_window)
find_entry.pack()
def find():
student_id = find_entry.get()
if student_id:
result = self.data.loc[self.data['学号'] == student_id]
if len(result) > 0:
messagebox.showinfo(title='查询结果', message=result.to_string(index=False))
else:
messagebox.showerror(title='错误', message='未找到学生信息')
else:
messagebox.showerror(title='错误', message='请输入学号')
tk.Button(find_window, text='查找', command=find).pack(pady=10)
def export_data(self):
file_path = filedialog.asksaveasfilename(title='保存文件', defaultextension='.xlsx')
if file_path:
self.data.to_excel(file_path, index=False)
messagebox.showinfo(title='提示', message='导出成功')
def plot_scores(self):
top = tk.Toplevel()
top.title('成绩表')
x_column_label = tk.Label(top, text='x轴:')
x_column_label.pack()
x_column_entry = tk.Entry(top)
x_column_entry.pack()
y_column_label = tk.Label(top, text='y轴:')
y_column_label.pack()
y_column_entry = tk.Entry(top)
y_column_entry.pack()
chart_type_label = tk.Label(top, text='Chart Type (line/bar):')
chart_type_label.pack()
chart_type_entry = tk.Entry(top)
chart_type_entry.pack()
plot_button = tk.Button(top, text='Plot', command=lambda: self.handle_plot_scores(top, x_column_entry.get(), y_column_entry.get(), chart_type_entry.get()))
plot_button.pack()
def handle_plot_scores(self, top, x_column, y_column, chart_type):
if not x_column or not y_column:
messagebox.showerror(title='错误', message='请填写完整信息')
else:
try:
fig, ax = plt.subplots(figsize=(8, 6))
if chart_type == 'line':
ax.plot(self.data[x_column], self.data[y_column])
elif chart_type == 'bar':
ax.bar(self.data[x_column], self.data[y_column])
else:
messagebox.showerror(title='错误', message='无效的图表类型')
return
ax.set_xlabel(x_column)
ax.set_ylabel(y_column)
ax.set_title('成绩分布图')
canvas = FigureCanvasTkAgg(fig, top)
canvas.draw()
canvas.get_tk_widget().pack()
except KeyError:
messagebox.showerror(title='错误', message='无效的列名')
except ValueError:
messagebox.showerror(title='错误', message='无效的数据类型')
root = tk.Tk() GradeManagementSystem(root) root.mainloop()
原文地址: https://www.cveoy.top/t/topic/oRJH 著作权归作者所有。请勿转载和采集!