tkinter dynamic Checkbutton获取返回值实现问答跳转问题求助
问题修正方案
原代码核心问题
- 变量作用域错误:当前题目对应的正确分组
key、问题Q均为全局变量,循环后只保留最后一次赋值的结果,出题时无法拿到当前题目的正确校验依据 - Checkbutton变量定义错误:
chkValue初始为单个IntVar实例,无法按下标存储多个选项的选中状态 - 界面组件未做重置:每次出题没有清空上一轮的组件,会导致界面元素堆叠无法使用
- 事件绑定逻辑不合理:给每个Checkbutton绑定跳转事件,用户刚选第一个选项就会触发下一题,不符合答题交互逻辑
实现思路调整
- 采用Tkinter原生的事件驱动模式,不需要主动暂停程序,新增提交按钮,用户完成选择后主动点击触发校验即可
- 每次出题前清空上一轮的所有问题、选项、按钮组件
- 用列表存储每个选项对应的选中状态变量,提交时遍历校验选中值是否属于当前分组
- 把当前题目对应的正确分组、选项列表存在全局变量,供校验函数调用
可运行修正代码
import tkinter as tk from tkinter import messagebox import random # 初始化窗口 window = tk.Tk() window.geometry("400x300") # 全局变量存储当前题目相关信息 current_correct_group = None current_question = None option_vars = [] option_widgets = [] submit_btn = None question_label = None def load_data(): # 读取文件构造分组字典 cpll = {} idx = 0 with open('cpll.txt', 'r', encoding='utf-8') as f: lines = f.readlines() for line in lines: if line == "\n": idx += 1 else: cpll.setdefault(idx, []).append(line.strip()) return cpll def clear_old_widgets(): # 清空上一轮的所有组件 global question_label, submit_btn if question_label: question_label.destroy() for widget in option_widgets: widget.destroy() if submit_btn: submit_btn.destroy() option_vars.clear() option_widgets.clear() def quiz(): global current_correct_group, current_question, question_label, submit_btn clear_old_widgets() # 随机选一个分组作为当前正确分组 current_correct_group = random.choice(list(cpll.values())) # 抽一个当问题 current_question = random.choice(current_correct_group) # 生成备选答案:当前分组剩余元素 + 其他分组随机选2个干扰项,不需要干扰项可删除对应逻辑 options = [i for i in current_correct_group if i != current_question] other_groups = [v for k,v in cpll.items() if v != current_correct_group] for g in other_groups: options.extend(random.sample(g, 1)) # 打乱选项 random.shuffle(options) # 展示问题 question_label = tk.Label(window, text=f"请选择与【{current_question}】同组的选项", bg="skyblue", width=40) question_label.pack(pady=10) # 生成选项Checkbutton for opt in options: var = tk.IntVar() chk = tk.Checkbutton(window, text=opt, variable=var) chk.pack(anchor='w', padx=50) option_vars.append((opt, var)) option_widgets.append(chk) # 提交按钮 submit_btn = tk.Button(window, text="提交答案", command=check_answer) submit_btn.pack(pady=15) def check_answer(): # 校验选中的选项是否都属于当前正确分组 selected = [opt for opt, var in option_vars if var.get() == 1] all_correct = all([i in current_correct_group for i in selected]) if all_correct and len(selected) > 0: # 答对进入下一轮 quiz() else: # 答错提示 messagebox.showwarning("错误", "选择有误,请重新选择") # 加载数据 cpll = load_data() # 开始第一轮出题 quiz() window.mainloop()
内容的提问来源于stack exchange,提问作者user1582596
相关产品推荐
相关产品推荐

