import tkinter as tk
from tkinter import ttk, messagebox
import random
import time
from datetime import datetime
class AbacusTest:
def __init__(self):
self.root = tk.Tk()
self.root.title("珠算测试器")
self.root.geometry("800x600")
# 测试相关变量
self.username = ""
self.questions = []
self.current_question = 0
self.correct_count = 0
self.start_time = None
self.timer_running = False
# 添加算盘状态变量
self.upper_beads = [[False] * 1 for _ in range(5)] # 上珠状态
self.lower_beads = [[False] * 4 for _ in range(5)] # 下珠状态
self.setup_ui()
def setup_ui(self):
"""设置用户界面"""
# 用户信息框架
self.info_frame = ttk.Frame(self.root)
self.info_frame.pack(pady=10)
ttk.Label(self.info_frame, text="用户名:").pack(side=tk.LEFT)
self.username_entry = ttk.Entry(self.info_frame)
self.username_entry.pack(side=tk.LEFT, padx=5)
self.start_button = ttk.Button(self.info_frame, text="开始测试", command=self.start_test)
self.start_button.pack(side=tk.LEFT, padx=5)
# 计时器显示
self.timer_label = ttk.Label(self.root, text="00:00", font=("Arial", 20))
self.timer_label.pack(pady=5)
# 题目显示区
self.question_frame = ttk.Frame(self.root)
self.question_frame.pack(pady=10)
self.question_label = ttk.Label(self.question_frame, text="", font=("Arial", 16))
self.question_label.pack()
# 算盘区域
self.canvas = tk.Canvas(self.root, width=400, height=300, bg='#F5F5DC')
self.canvas.pack(pady=10)
self.canvas.bind('<Button-1>', self.move_bead)
self.draw_abacus()
# 答题统计
self.stats_frame = ttk.Frame(self.root)
self.stats_frame.pack(pady=10)
self.stats_label = ttk.Label(self.stats_frame, text="总题数: 0 已答题数: 0 正确题数: 0")
self.stats_label.pack()
# 确认按钮
self.confirm_button = ttk.Button(self.root, text="确认答案", command=self.check_answer)
self.confirm_button.pack(pady=5)
self.confirm_button["state"] = "disabled"
def start_test(self):
"""开始测试"""
if not self.username_entry.get().strip():
messagebox.showerror("错误", "请输入用户名")
return
self.username = self.username_entry.get()
self.generate_questions()
self.start_time = time.time()
self.timer_running = True
self.update_timer()
self.show_question()
self.username_entry["state"] = "disabled"
self.start_button["state"] = "disabled"
self.confirm_button["state"] = "normal"
def generate_questions(self):
"""生成测试题目"""
self.questions = []
for _ in range(10): # 生成10道题
num1 = random.randint(1, 999)
num2 = random.randint(1, 999)
op = random.choice(['+', '-'])
answer = num1 + num2 if op == '+' else num1 - num2
self.questions.append({
'question': f"{num1} {op} {num2} = ?",
'answer': answer
})
def show_question(self):
"""显示当前题目"""
if self.current_question < len(self.questions):
self.question_label["text"] = self.questions[self.current_question]['question']
self.update_stats()
def draw_abacus(self):
"""绘制算盘"""
self.canvas.delete("abacus")
# 绘制外框和内框
self.canvas.create_rectangle(25, 25, 375, 295, fill='black', outline='black', tags="abacus")
self.canvas.create_rectangle(28, 28, 372, 292, fill='white', outline='black', tags="abacus")
# 绘制横梁
self.canvas.create_rectangle(28, 120, 372, 140, fill='brown', outline='black', tags="abacus")
# 绘制上珠
for i in range(5):
y_pos = 50 if not self.upper_beads[i][0] else 80
self.canvas.create_oval(60 + i * 65, y_pos, 110 + i * 65, y_pos + 40,
fill='orange', outline='black', tags="abacus")
# 绘制下珠
for i in range(5):
for j in range(4):
y_pos = 160 + j * 30 if not self.lower_beads[i][j] else 140 + j * 30
self.canvas.create_oval(60 + i * 65, y_pos, 110 + i * 65, y_pos + 25,
fill='yellow', outline='black', tags="abacus")
def move_bead(self, event):
"""处理珠子移动"""
x, y = event.x, event.y
# 处理上珠
for i in range(5):
if 60 + i * 65 <= x <= 110 + i * 65 and 50 <= y <= 120:
self.upper_beads[i][0] = not self.upper_beads[i][0]
self.draw_abacus()
return
# 处理下珠
for i in range(5):
for j in range(4):
if 60 + i * 65 <= x <= 110 + i * 65 and 160 + j * 30 <= y <= 185 + j * 30:
if self.lower_beads[i][j]:
for k in range(j, 4):
self.lower_beads[i][k] = False
else:
for k in range(j + 1):
self.lower_beads[i][k] = True
self.draw_abacus()
return
def get_abacus_value(self):
"""获取算盘当前值"""
total = 0
for i in range(5):
column_value = 0
# 计算上珠值(5)
if self.upper_beads[i][0]:
column_value += 5
# 计算下珠值(1-4)
for j in range(4):
if self.lower_beads[i][j]:
column_value += 1
# 根据位置计算实际值
total += column_value * (10 ** (4-i))
return total
def check_answer(self):
"""检查答案"""
current_value = self.get_abacus_value()
correct_answer = self.questions[self.current_question]['answer']
if current_value == correct_answer:
self.correct_count += 1
messagebox.showinfo("结果", "回答正确!")
else:
messagebox.showinfo("结果", f"回答错误。\n你的答案:{current_value}\n正确答案:{correct_answer}")
self.current_question += 1
if self.current_question < len(self.questions):
# 重置算盘状态
self.upper_beads = [[False] * 1 for _ in range(5)]
self.lower_beads = [[False] * 4 for _ in range(5)]
self.draw_abacus()
self.show_question()
else:
self.end_test()
def update_timer(self):
"""更新计时器"""
if self.timer_running:
elapsed = int(time.time() - self.start_time)
minutes = elapsed // 60
seconds = elapsed % 60
self.timer_label["text"] = f"{minutes:02d}:{seconds:02d}"
self.root.after(1000, self.update_timer)
def update_stats(self):
"""更新统计信息"""
self.stats_label["text"] = (
f"总题数: {len(self.questions)} "
f"已答题数: {self.current_question} "
f"正确题数: {self.correct_count}"
)
def end_test(self):
"""结束测试"""
self.timer_running = False
elapsed_time = int(time.time() - self.start_time)
score = int(self.correct_count / len(self.questions) * 100)
result = (
f"测试结果\n"
f"用户名:{self.username}\n"
f"用时:{elapsed_time//60}分{elapsed_time%60}秒\n"
f"总题数:{len(self.questions)}\n"
f"正确题数:{self.correct_count}\n"
f"得分:{score}分"
)
messagebox.showinfo("测试完成", result)
self.root.quit()
def run(self):
"""运行测试器"""
self.root.mainloop()
# 创建并运行测试器
if __name__ == "__main__":
test = AbacusTest()
test.run()