如何基于Tkinter Entry实现可重复打分按钮 解决列表重复追加报错问题
词汇测试打分按钮重复点击问题修复方案
问题根因
- 全局列表
grade未在每次打分前清空,每次点击都会追加新的判断结果,导致对错统计列表长度持续增长 - 每次打分都会新建O/X标签插入页面,旧标签未被清理,多次点击后同一位置堆叠多个标签出现重叠
- 之前尝试重置列表未生效的原因是:在函数内直接写
grade = []是创建了局部变量,没有修改外部的全局grade列表
修复步骤
- 提前为每个单词创建结果展示标签,初始状态为空,避免每次打分重复新建标签
- 每次触发打分函数时,先清空
grade全局列表的历史数据 - 直接更新提前创建的结果标签的文本内容,不需要每次新建组件
完整可运行修改后代码
import tkinter from tkinter import * window = tkinter.Tk() container = tkinter.Frame(window) canvas = tkinter.Canvas(container) window.title('词汇测试工具') window.geometry('640x480') window.resizable(True, True) scrollbar = tkinter.Scrollbar(container, orient="vertical", command=canvas.yview) # 滚动区域配置 main_frame = Frame(window) main_frame.pack(fill=BOTH, expand=1) my_canvas = Canvas(main_frame) my_canvas.pack(side=LEFT, fill=BOTH, expand=1) my_scrollbar = tkinter.Scrollbar(main_frame, orient=VERTICAL, command=my_canvas.yview) my_scrollbar.pack(side=RIGHT, fill=Y) my_canvas.configure(yscrollcommand=my_scrollbar.set) my_scrollbar.bind('<Configure>', lambda e: my_canvas.configure(scrollregion= my_canvas.bbox("all"))) second_frame = Frame(my_canvas) my_canvas.create_window((0,0), window= second_frame, anchor="nw") def mouse_scroll(event): my_canvas.yview_scroll(-1 * int((event.delta / 120)), "units") my_canvas.bind_all("<MouseWheel>", mouse_scroll) def getEntry( i ): return list( second_frame.children.values() )[ i ] Day21_eng = ['exquisite', 'acquisition', 'regulate', 'transportation', 'insight', 'straightforward', 'cultivate', 'innovation', 'preserve', 'odor', 'exception', 'munch', 'proclaim', 'slap', 'variability', 'investigate', 'flare', 'outpace', 'genuine', 'plead', 'fossilize', 'toil', 'drastic', 'withhold', 'inanimate', 'clockwise', 'amnesia', 'revive', 'theorize', 'culprit', 'limp', 'worn-out', 'indignity', 'span', 'bribe'] Day21_kor = [['우아한', '정교한', '절묘한'], ['취득', '획득', '습득'], ['규제하다', '통제하다'], ['운송', '운임', '추방'], ['통찰', '통찰력'], ['명확한', '솔직한'], ['경작하다', '기르다', '장려하다', '육성하다'], ['혁신'], ['보전', '보호지', '보호하다', '보존하다'], ['냄새', '악취', '기미', '낌새'], ['예외'], ['우적우적 먹다'], ['선언하다'], ['찰싹 때리다'], ['변화성', '가변성', '변용성'], ['조사하다'], ['불끈 성나게 하다', '이글거리다', '불꽃', '타오름'], ['앞지르다', '속도가 더 빠르다'], ['진짜의', '진품의'], ['탄원하다', '변호하다', '애원하다'], ['고착화하다', '화석화하다'], ['수고', '노고', '힘들게 일하다'], ['급격한', '극단적인'], ['보류하다', '유보하다'], ['생명 없는', '무생물의'], ['시계방향으로'], ['기억상실'], ['부활시키다', '되살아나게 하다'], ['이론화하다'], ['죄인', '범죄자', '장본인'], ['절뚝거리다', '느릿느릿 가다', '기운이 없는','축 처진'], ['닳아빠진', '진부한', '지친'], ['모욕', '무례', '치욕'], ['기간', '폭', '범위', '걸치다', '이르다'], ['뇌물을 주다', '뇌물']] entries = [] grade = [] result_labels = [] # 新增:存储结果标签的列表 def check(): global grade # 声明使用全局的grade列表 grade.clear() # 清空上次的打分结果 # 清空所有上次的结果显示 for label in result_labels: label.config(text='') # 重新打分 for i, e in enumerate(entries): value = e.get().strip() is_correct = value in Day21_kor[i] grade.append(is_correct) # 直接更新对应位置的结果标签 if is_correct: result_labels[i].config(text='O', fg='Blue') else: result_labels[i].config(text='X', fg='red') # 控制台打印统计 right = [i for i, val in enumerate(grade) if val] wrong = [i for i, val in enumerate(grade) if not val] print(f"正确题序号:{right}") print(f"错误题序号:{wrong}") print(f"正确率:{len(right)}/{len(Day21_eng)}") # 生成单词、输入框、结果标签 for row, item in enumerate(Day21_eng): # 单词标签 label_word = tkinter.Label(second_frame, text= item) label_word.grid(column=0, row=row) # 输入框 entry = tkinter.Entry(second_frame, width=30) entry.grid(row=row, column=1, sticky='nsew') entry.bind('<Return>', getEntry) entries.append(entry) # 新增:提前创建结果标签,初始为空 result_label = tkinter.Label(second_frame, text='') result_label.grid(column=3, row=row) result_labels.append(result_label) # 打分按钮 b_check = tkinter.Button(second_frame, text='打分', command=check) b_check.grid(columnspan=2, row=len(Day21_eng)) window.mainloop()
优化点说明
- 新增了
result_labels列表存储所有结果标签,每次打分直接更新标签内容,不需要重复创建组件,避免重叠 - 每次打分前先清空
grade列表和所有结果标签的历史内容,不会出现数据累加的问题 - 优化了对错判断逻辑,直接用布尔值存储结果,不需要转字符串判断
- 新增了正确率统计,方便查看测试结果
内容的提问来源于stack exchange,提问作者tunatuna123
相关产品推荐
相关产品推荐

