我创建了一个图形测验。当我在减法测验中按下多项选择按钮时,Tkinter 窗口崩溃。它不会在任何其他类型的测验中崩溃。有时,当我单击多项选择按钮时,它会起作用,但只会进一步崩溃到测验中:
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":
create_quiz("Subtraction", lambda: (random.randint(0, 100), random.randint(0, 100)), 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()
我在两台设备上尝试过,但也不起作用。该按钮变灰,Tkinter 窗口停止响应。
问题是
update_question()
中的无限循环。当减法问题的答案小于 -10 时,就会发生这种情况。发生这种情况时,该函数无法在 correct_answer-10
和 correct_answer+10
之间生成满足 choice >= 0
的答案选择。这会导致无限循环,因为 len(choices) < 4
始终为 true。
# If the answer is less than -10:
while len(choices) < 4: # Always true
choice = random.randint(correct_answer - 10, correct_answer + 10) # Always < 0
if choice not in choices and choice >= 0: # Always false
choices.append(choice)
您有几种解决此问题的选项。一是完全删除
choice >= 0
并允许否定答案。如果您仍然想将答案限制为非负数,您可以在问题生成器中添加一些代码,以在需要时交换 x
和 y
:
def create_quiz(...):
...
for _ in range(10):
x, y = question_generator()
answer = answer_function(x, y)
if answer < 0:
x, y = y, x
answer = answer_function(x, y)
quiz_questions.append((x, y))
quiz_answers.append(answer)
...