import csv import tkinter as tk from tkinter import ttk, messagebox from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg import matplotlib.pyplot as plt def process_csv(filename): try: with open(filename, 'r', encoding='utf-8-sig') as csvfile: reader = csv.DictReader(csvfile) data = list(reader) data = sorted(data, key=lambda x: int(x['成绩']), reverse=True) return data except FileNotFoundError: messagebox.showerror("错误", f"文件未找到: {filename}") return [] except ValueError: messagebox.showerror("错误", "成绩格式错误,请确保为整数") return [] except Exception as e: messagebox.showerror("错误", f"处理CSV时出错:{e}") return [] def show_chart(infos, parent): import matplotlib matplotlib.rcParams['font.sans-serif'] = ['SimHei'] # 支持中文 matplotlib.rcParams['axes.unicode_minus'] = False names = [i['姓名'] for i in infos] scores = [int(i['成绩']) for i in infos] fig, ax = plt.subplots(figsize=(6, 3)) ax.bar(names, scores, color='#66b3ff') ax.set_title('学生成绩柱状图') ax.set_ylabel('成绩') ax.set_xlabel('姓名') plt.xticks(rotation=45) canvas = FigureCanvasTkAgg(fig, master=parent) canvas.draw() canvas.get_tk_widget().pack(pady=10) def display_scores(infos): window = tk.Tk() window.title('学生成绩排行榜') window.geometry('650x700') window.configure(bg='#f0f4f7') # 标题 tk.Label(window, text="学生成绩排行榜", bg='#f0f4f7', fg='#336699', font=('Arial', 20, 'bold')).pack(pady=10) # 搜索框 search_frame = tk.Frame(window, bg='#f0f4f7') search_frame.pack() tk.Label(search_frame, text="搜索姓名:", bg='#f0f4f7').pack(side=tk.LEFT) search_entry = tk.Entry(search_frame) search_entry.pack(side=tk.LEFT) # 表格 columns = ('姓名', '成绩') tree = ttk.Treeview(window, columns=columns, show='headings', height=10) tree.heading('姓名', text='姓名') tree.heading('成绩', text='成绩') tree.column('姓名', anchor='center', width=200) tree.column('成绩', anchor='center', width=100) style = ttk.Style() style.configure('Treeview', font=('Arial', 12), rowheight=28) style.configure('Treeview.Heading', font=('Arial', 13, 'bold')) def populate_table(data): for item in tree.get_children(): tree.delete(item) for info in data: score = int(info['成绩']) tag = 'normal' if score >= 90: tag = 'excellent' elif score < 60: tag = 'fail' tree.insert('', tk.END, values=(info['姓名'], info['成绩']), tags=(tag,)) # 打标签上色 tree.tag_configure('excellent', background='#d4edda') # 绿色 tree.tag_configure('fail', background='#f8d7da') # 红色 populate_table(infos) tree.pack(pady=10) # 成绩统计 def show_stats(data): if not data: return scores = [int(i['成绩']) for i in data] avg = sum(scores) / len(scores) highest = max(scores) count = len(scores) stats_label.config(text=f"平均分:{avg:.2f},最高分:{highest},总人数:{count}") stats_label = tk.Label(window, bg='#f0f4f7', font=('Arial', 12)) stats_label.pack(pady=5) show_stats(infos) # 搜索功能 def search(): name = search_entry.get().strip() if not name: populate_table(infos) show_stats(infos) return filtered = [i for i in infos if name in i['姓名']] populate_table(filtered) show_stats(filtered) tk.Button(search_frame, text="搜索", command=search).pack(side=tk.LEFT, padx=5) # 重新加载按钮 def reload(): new_data = process_csv('score.csv') if new_data: nonlocal infos infos = new_data populate_table(infos) show_stats(infos) tk.Button(window, text="重新加载成绩", command=reload).pack(pady=10) # 可视化柱状图 show_chart(infos, window) window.mainloop() if __name__ == "__main__": score_data = process_csv('students.csv') if score_data: display_scores(score_data)