import tkinter as tk from tkinter import messagebox, simpledialog import time import requests API_URL = "http://47.80.30.142:6364" # Flask 接口地址 # 读取排行榜数据(从 Flask 获取) def load_leaderboard(): try: resp = requests.get(f"{API_URL}/get_board") if resp.status_code == 200: return resp.json() else: return [] except Exception as e: messagebox.showerror("错误", f"无法加载排行榜数据:{e}") return [] # 获取参赛者姓名 def get_player_name(): name = simpledialog.askstring("参赛者姓名", "请输入您的姓名:") if not name: messagebox.showwarning("警告", "姓名不能为空,请重新输入。") return get_player_name() return name # 上传成绩并刷新排行榜 def submit_result(name, error): try: # 先下载当前排行榜 leaderboard = load_leaderboard() # 查找或更新当前用户成绩(误差更小的) found = False for entry in leaderboard: if entry["name"] == name: found = True if abs(error) < entry["error"]: entry["error"] = round(abs(error), 3) break if not found: leaderboard.append({"name": name, "error": round(abs(error), 3)}) # 按误差升序排序 leaderboard.sort(key=lambda x: x["error"]) # 提交新的排行榜到服务器 resp = requests.post(f"{API_URL}/set_board", json=leaderboard) if resp.status_code == 200: update_rank_display(leaderboard) else: messagebox.showerror("提交失败", "提交成绩失败,请稍后再试。") except Exception as e: messagebox.showerror("错误", f"提交成绩时出错:{e}") # 显示排行榜 def update_rank_display(leaderboard): rank_listbox.delete(0, tk.END) for i, entry in enumerate(leaderboard, 1): n, e = entry["name"], entry["error"] rank_listbox.insert(tk.END, f"{i}. {n:<8} 误差: {e:.3f}s") # 更新时间函数 def update_time(): if flag: now = time.time() timex = now - start_time timex_label.config(text=f"⏱ 时间:{timex:.3f} 秒") root.after(10, update_time) def show_win_animation(): anim = tk.Toplevel(root) anim.geometry("320x200") anim.title("🎉 胜利动画") anim.configure(bg="#ffffff") anim.attributes("-topmost", True) label = tk.Label(anim, text="🎉 完美掌控时间!🎉", font=("微软雅黑", 18, "bold"), bg="#ffffff") label.pack(expand=True) colors = ["#ff6666", "#66cc66", "#3399ff", "#ffcc00", "#cc66ff"] sizes = [18, 22, 26, 30, 26, 22, 18] def animate(i=0): if i < len(sizes): label.config(font=("微软雅黑", sizes[i], "bold"), fg=colors[i % len(colors)]) anim.after(150, animate, i + 1) else: anim.destroy() animate() # 控制开始/停止 def change(): global flag, start_time if not flag: flag = True start_time = time.time() update_time() else: flag = False end_time = time.time() timex = end_time - start_time error = timex - 10 timex_label.config(text=f"✅ 实际时间:{timex:.3f} 秒\n误差:{error:.3f} 秒") name = get_player_name() submit_result(name, error) if abs(error) < 0.01: show_win_animation() else: messagebox.showinfo("结果", "还差一点点,再接再厉吧!") # ================================ # 主窗口 # ================================ root = tk.Tk() root.geometry("340x500") root.title("10秒挑战") root.configure(bg="#f0faff") # 标题 title_label = tk.Label(root, text="🎯 10 秒挑战 🎯", font=("微软雅黑", 18, "bold"), fg="#004466", bg="#f0faff") title_label.pack(pady=15) # 排行榜框 rank_frame = tk.Frame(root, bg="#ffffff", bd=2, relief="groove") rank_frame.pack(pady=10) rank_title = tk.Label(rank_frame, text="🏆 排行榜(误差越小越靠前)", font=("微软雅黑", 10, "bold"), bg="#ffffff", fg="#333333") rank_title.pack(pady=(5, 0)) rank_listbox = tk.Listbox(rank_frame, font=("Courier", 10), height=5, width=35, bg="#f9f9f9") rank_listbox.pack(padx=10, pady=5) # 初始显示排行榜 leaderboard = load_leaderboard() update_rank_display(leaderboard) # 时间标签 timex_label = tk.Label(root, text="点击按钮开始挑战", font=("微软雅黑", 12), bg="#f0faff", fg="#333333") timex_label.pack(pady=20) # 按钮 start_button = tk.Button(root, text="🎮 开始 / 停止", font=("微软雅黑", 12, "bold"), bg="#66ccff", fg="white", activebackground="#3399cc", width=20, height=2, command=change, relief="raised", bd=3) start_button.pack(pady=30) # 控制变量 flag = False start_time = 0 # 启动主循环 root.mainloop()