Tkinter减法测验选择题按钮点击后程序崩溃问题求助
问题诊断与修复方案
核心问题
程序在减法选择题模式下崩溃,根源是死循环阻塞了Tkinter主事件循环:
- 减法题目生成时,
x和y均为0-100的随机数,会出现x < y的情况,导致正确答案为负数。 - 生成选择题选项的逻辑中,强制要求
choice >= 0,当正确答案是负数时,random.randint(correct_answer -10, correct_answer +10)生成的所有候选值都是负数,永远无法满足choice >=0的条件,while len(choices) <4会无限循环,最终导致窗口无响应。
修复方案
方案1:确保减法题答案非负(推荐,符合常规测验逻辑)
修改减法题的题目生成逻辑,保证x >= y,避免出现负数答案:
# 在start_quiz函数中,替换减法对应的代码块 elif operation == "Subtraction": # 生成x >= y的数对,保证答案非负 def subtract_question_generator(): y = random.randint(0, 100) x = random.randint(y, 100) return (x, y) create_quiz("Subtraction", subtract_question_generator, lambda x, y: x - y, quiz_type)
方案2:允许负数选项(适合需要练习负数减法的场景)
如果需要保留负数答案的题目,移除选项必须非负的限制:
# 在update_question函数中,修改选项生成的条件判断 while len(choices) < 4: choice = random.randint(correct_answer - 10, correct_answer + 10) if choice not in choices: # 去掉choice >=0的限制 choices.append(choice)
完整修复后的代码(采用方案1)
import tkinter as tk import random def main_menu(): clear_window() root.configure(bg='DodgerBlue4') title = tk.Label(root, text="Math Quiz", font=("Arial", 32), bg='DodgerBlue4', fg='white') title.pack(pady=40) button_frame = tk.Frame(root, bg='DodgerBlue4') button_frame.pack(pady=20) operations = [ ("Multiplication", lambda: select_quiz_type('Multiplication'), 'red'), ("Addition", lambda: select_quiz_type('Addition'), 'forest green'), ("Subtraction", lambda: select_quiz_type('Subtraction'), 'blue'), ("Division", lambda: select_quiz_type('Division'), 'gold'), ] for operation, command1, color in operations: if command1: tk.Button(button_frame, text=operation, font=("Arial", 18), command=command1, bg=color, fg='white', width=12).pack(side='left', padx=20) def clear_window(): for widget in root.winfo_children(): widget.destroy() def select_quiz_type(operation): clear_window() root.configure(bg='DodgerBlue4') label = tk.Label(root, text=f"{operation} Quiz Type", font=("Arial", 24), bg='DodgerBlue4', fg='white') label.pack(pady=20) button_frame = tk.Frame(root, bg='DodgerBlue4') button_frame.pack(pady=20) tk.Button(button_frame, text="Multiple Choice", font=("Arial", 18), command=lambda: start_quiz(operation, "multiple_choice"), bg='gold', fg='black').pack(side='left', padx=20) tk.Button(button_frame, text="Submit Box", font=("Arial", 18), command=lambda: start_quiz(operation, "submit_box"), bg='gold', fg='black').pack(side='left', padx=20) def start_quiz(operation, quiz_type): if operation == "Multiplication": create_quiz("Multiplication", lambda: (random.randint(1, 12), random.randint(1, 12)), lambda x, y: x * y, quiz_type) elif operation == "Addition": create_quiz("Addition", lambda: (random.randint(0, 100), random.randint(0, 100)), lambda x, y: x + y, quiz_type) elif operation == "Subtraction": # 修改减法题目生成逻辑,确保x >= y def subtract_question_generator(): y = random.randint(0, 100) x = random.randint(y, 100) return (x, y) create_quiz("Subtraction", subtract_question_generator, lambda x, y: x - y, quiz_type) elif operation == "Division": create_quiz("Division", lambda: (random.randint(1, 100), random.randint(1, 10)), lambda x, y: x // y if y != 0 else 1, quiz_type) def create_quiz(title, question_generator, answer_function, quiz_type): global current_operation, quiz_questions, quiz_answers, current_question, score, question_label, answer_buttons, answer_entry, current_quiz_type clear_window() current_operation = title.split()[0] current_quiz_type = quiz_type tk.Label(root, text=f"{title} Quiz", font=("Arial", 24), bg='DodgerBlue4', fg='white').pack(pady=20) quiz_questions = [] quiz_answers = [] for _ in range(10): x, y = question_generator() quiz_questions.append((x, y)) quiz_answers.append(answer_function(x, y)) current_question = 0 score = 0 question_label = tk.Label(root, font=("Arial", 18), bg='DodgerBlue4', fg='white') question_label.pack(pady=20) if quiz_type == "multiple_choice": answer_buttons = [] for i in range(4): btn = tk.Button(root, font=("Arial", 18), bg='gold', fg='black', command=lambda control=i: check_mp_ans(control)) btn.pack(pady=5) answer_buttons.append(btn) else: answer_entry = tk.Entry(root, font=("Arial", 18)) answer_entry.pack(pady=10) tk.Button(root, text="Submit", font=("Arial", 18), command=check_sb_ans, bg='gold', fg='black').pack(pady=20) update_question() def update_question(): global current_question, quiz_questions, question_label, quiz_answers, current_quiz_type, answer_buttons if current_question < len(quiz_questions): x, y = quiz_questions[current_question] symbol = 'x' if current_operation == 'Multiplication' else '+' if current_operation == 'Addition' else '-' if current_operation == 'Subtraction' else '/' question_label.config(text=f"Question {current_question + 1}: {x} {symbol} {y} = ?") if current_quiz_type == "multiple_choice": correct_answer = quiz_answers[current_question] choices = [correct_answer] while len(choices) < 4: choice = random.randint(correct_answer - 10, correct_answer + 10) if choice not in choices and choice >= 0: choices.append(choice) random.shuffle(choices) for i, choice in enumerate(choices): answer_buttons[i].config(text=str(choice)) else: show_results() def check_mp_ans(control): global current_question, score, quiz_answers selected_answer = int(answer_buttons[control].cget('text')) correct_answer = quiz_answers[current_question] if selected_answer == correct_answer: score += 1 result_text = "Correct!" else: result_text = f"Wrong! The correct answer was {correct_answer}." current_question += 1 show_answer_result(result_text) def check_sb_ans(): global current_question, score, quiz_answers, answer_entry try: user_answer = int(answer_entry.get()) except ValueError: user_answer = None correct_answer = quiz_answers[current_question] if user_answer == correct_answer: score += 1 result_text = "Correct!" else: result_text = f"Wrong! The correct answer was {correct_answer}." current_question += 1 answer_entry.delete(0, tk.END) show_answer_result(result_text) def show_answer_result(result_text): clear_window() root.configure(bg='DodgerBlue4') tk.Label(root, text=result_text, font=("Arial", 24), bg='DodgerBlue4', fg='white').pack(pady=20) tk.Button(root, text="Next", font=("Arial", 18), command=recreate_question_interface, bg='gold', fg='black').pack(pady=20) def recreate_question_interface(): clear_window() global question_label, answer_buttons, answer_entry question_label = tk.Label(root, font=("Arial", 18), bg='DodgerBlue4', fg='white') question_label.pack(pady=20) if current_quiz_type == "multiple_choice": answer_buttons = [] for i in range(4): btn = tk.Button(root, font=("Arial", 18), bg='gold', fg='black', command=lambda control=i: check_mp_ans(control)) btn.pack(pady=5) answer_buttons.append(btn) else: answer_entry = tk.Entry(root, font=("Arial", 18)) answer_entry.pack(pady=10) tk.Button(root, text="Submit", font=("Arial", 18), command=check_sb_ans, bg='gold', fg='black').pack(pady=20) update_question() def show_results(): global score, quiz_questions clear_window() root.configure(bg='DodgerBlue4') tk.Label(root, text="Quiz Complete!", font=("Arial", 24), bg='DodgerBlue4', fg='white').pack(pady=20) tk.Label(root, text=f"Your score: {score}/{len(quiz_questions)}", font=("Arial", 18), bg='DodgerBlue4', fg='white').pack(pady=10) tk.Button(root, text="Main Menu", font=("Arial", 18), command=main_menu, bg='gold', fg='black').pack(pady=20) root = tk.Tk() root.geometry("900x600") main_menu() root.mainloop()
内容的提问来源于stack exchange,提问作者Anish Patil
相关产品推荐
相关产品推荐

