import tkinter as tk
from tkinter import messagebox, font
import random
import pygame
from pypinyin import pinyin, Style
# 初始化pygame混音器
pygame.mixer.init()
# 拼音组件 - 简化版,适合一年级学生
INITIALS = ['b', 'p', 'm', 'f', 'd', 't', 'n', 'l', 'g', 'k', 'h', 'j', 'q', 'x']
FINALS = ['a', 'o', 'e', 'i', 'u', 'ü', 'ai', 'ei', 'ao', 'ou', 'ie', 'üe', 'er', 'an', 'en', 'ang', 'eng', 'ong']
TONES = ['1', '2', '3', '4'] # 1: 一声, 2: 二声, 3: 三声, 4: 四声
class KidPinyinTrainer:
def __init__(self, root):
self.root = root
self.root.title("小小拼音王")
self.root.geometry("900x700")
self.root.configure(bg='#FFECD6') # 柔和的背景色
# 使用更大的字体
self.big_font = font.Font(family='Arial', size=24, weight='bold')
self.medium_font = font.Font(family='Arial', size=18)
self.small_font = font.Font(family='Arial', size=14)
# 训练数据
self.current_question = 0
self.correct_answers = 0
self.total_questions = 10
self.current_pinyin = ""
self.questions = []
# 创建界面
self.create_widgets()
self.start_new_round()
def create_widgets(self):
"""创建界面组件"""
# 顶部信息显示
self.info_label = tk.Label(self.root, text="", font=self.medium_font, bg='#FFECD6', fg='#E74C3C')
self.info_label.pack(pady=10)
# 拼音显示区域
self.pinyin_frame = tk.Frame(self.root, bg='#FFECD6')
self.pinyin_frame.pack(pady=20)
self.pinyin_label = tk.Label(self.pinyin_frame, text="?", font=('Arial', 72),
bg='#FFECD6', fg='#3498DB')
self.pinyin_label.pack()
# 播放按钮 - 更大的按钮
self.play_button = tk.Button(self.root, text="🔊 播放拼音", command=self.play_pinyin,
font=self.big_font, bg='#2ECC71', fg='white',
activebackground='#27AE60', height=2, width=15)
self.play_button.pack(pady=10)
# 选择区域
self.selection_frame = tk.Frame(self.root, bg='#FFECD6')
self.selection_frame.pack(pady=20)
# 声母选择
tk.Label(self.selection_frame, text="选择声母:", font=self.medium_font,
bg='#FFECD6', fg='#9B59B6').grid(row=0, column=0, sticky='w', columnspan=6)
self.initial_var = tk.StringVar()
for i, initial in enumerate(INITIALS):
rb = tk.Radiobutton(self.selection_frame, text=initial, variable=self.initial_var,
value=initial, font=self.big_font, bg='#FFECD6',
selectcolor='#AED6F1', indicatoron=0, width=3)
rb.grid(row=1+i//7, column=i%7, padx=5, pady=5)
# 韵母选择
tk.Label(self.selection_frame, text="选择韵母:", font=self.medium_font,
bg='#FFECD6', fg='#9B59B6').grid(row=3, column=0, sticky='w', columnspan=6)
self.final_var = tk.StringVar()
for i, final in enumerate(FINALS):
rb = tk.Radiobutton(self.selection_frame, text=final, variable=self.final_var,
value=final, font=self.big_font, bg='#FFECD6',
selectcolor='#AED6F1', indicatoron=0, width=3)
rb.grid(row=4+i//7, column=i%7, padx=5, pady=5)
# 声调选择
tk.Label(self.selection_frame, text="选择声调:", font=self.medium_font,
bg='#FFECD6', fg='#9B59B6').grid(row=7, column=0, sticky='w', columnspan=6)
self.tone_var = tk.StringVar()
tones_display = ['ˉ 一声', 'ˊ 二声', 'ˇ 三声', 'ˋ 四声']
for i, tone in enumerate(TONES):
rb = tk.Radiobutton(self.selection_frame, text=tones_display[i], variable=self.tone_var,
value=tone, font=self.medium_font, bg='#FFECD6',
selectcolor='#AED6F1', indicatoron=0, width=8)
rb.grid(row=8, column=i, padx=5, pady=5)
# 提交按钮 - 更大的按钮
self.submit_button = tk.Button(self.root, text="提交答案", command=self.check_answer,
font=self.big_font, bg='#E74C3C', fg='white',
activebackground='#C0392B', height=2, width=15)
self.submit_button.pack(pady=20)
# 添加一个可爱的图片标签 (实际使用时可以替换为真实的图片)
self.image_label = tk.Label(self.root, text="✏️ 学拼音真有趣!", font=self.big_font,
bg='#FFECD6', fg='#E67E22')
self.image_label.pack(pady=10)
def generate_questions(self):
"""生成一轮问题 - 使用更简单的拼音组合"""
self.questions = []
easy_initials = ['b', 'p', 'm', 'f', 'd', 't', 'n', 'l', 'g', 'k', 'h']
easy_finals = ['a', 'o', 'e', 'i', 'u', 'ai', 'ei', 'ao', 'ou', 'an', 'en', 'ang', 'eng']
for _ in range(self.total_questions):
initial = random.choice(easy_initials)
final = random.choice(easy_finals)
tone = random.choice(TONES)
self.questions.append({
'initial': initial,
'final': final,
'tone': tone,
'pinyin': f"{initial}{final}{tone}"
})
def start_new_round(self):
"""开始新一轮训练"""
self.current_question = 0
self.correct_answers = 0
self.generate_questions()
self.show_question()
def show_question(self):
"""显示当前问题"""
if self.current_question < self.total_questions:
question = self.questions[self.current_question]
self.current_pinyin = question['pinyin']
self.info_label.config(text=f"第 {self.current_question+1} 题 / 共 {self.total_questions} 题")
self.pinyin_label.config(text="?")
# 清除之前的选择
self.initial_var.set('')
self.final_var.set('')
self.tone_var.set('')
else:
# 一轮结束,显示结果
accuracy = (self.correct_answers / self.total_questions) * 100
if accuracy == 100:
message = f"太棒了!全对!\n你是拼音小达人!\n\n点击确定再来一轮吧!"
elif accuracy >= 80:
message = f"做得很好!\n正确率: {accuracy:.0f}%\n\n点击确定继续练习!"
elif accuracy >= 60:
message = f"不错哦!\n正确率: {accuracy:.0f}%\n\n再练习一次会更好!"
else:
message = f"加油!\n正确率: {accuracy:.0f}%\n\n多练习几次就会进步!"
messagebox.showinfo("练习结果", message)
self.start_new_round()
def play_pinyin(self):
"""播放当前拼音的读音"""
if self.current_question < self.total_questions:
question = self.questions[self.current_question]
pinyin_text = question['pinyin'][:-1] # 去掉声调数字
self.pinyin_label.config(text=pinyin_text)
# 在实际应用中,这里应该播放对应的拼音读音
# 例如: pygame.mixer.Sound(f"pinyin_audios/{pinyin_text}.wav").play()
# 临时解决方案:显示拼音文字
self.root.after(1000, lambda: self.pinyin_label.config(text="?"))
def check_answer(self):
"""检查答案是否正确"""
if not (self.initial_var.get() and self.final_var.get() and self.tone_var.get()):
messagebox.showwarning("提示", "小朋友,请选择声母、韵母和声调哦!")
return
user_answer = {
'initial': self.initial_var.get(),
'final': self.final_var.get(),
'tone': self.tone_var.get()
}
correct_answer = {
'initial': self.questions[self.current_question]['initial'],
'final': self.questions[self.current_question]['final'],
'tone': self.questions[self.current_question]['tone']
}
if user_answer == correct_answer:
self.correct_answers += 1
# 使用更可爱的正确提示
messagebox.showinfo("结果", "✅ 回答正确!\n\n太棒了!继续加油!")
else:
correct_pinyin = f"{correct_answer['initial']}{correct_answer['final']}"
tone_display = {'1': '一声', '2': '二声', '3': '三声', '4': '四声'}[correct_answer['tone']]
# 使用更友好的错误提示
messagebox.showinfo("结果", f"❌ 回答错了\n\n正确答案是:\n{correct_pinyin} ({tone_display})\n\n别灰心,再试试看!")
self.current_question += 1
self.show_question()
if __name__ == "__main__":
root = tk.Tk()
app = KidPinyinTrainer(root)
root.mainloop()