You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 03:54:54