如何填充Tkinter中通过循环创建的Entry输入框
解决循环创建Entry后仅填充最后一个输入框的问题
问题出在你循环创建Entry时,每次都把新的Entry赋值给同一个变量(比如strength),导致这个变量最终只指向最后一个创建的Entry,填充时自然只能操作这一个。要通过循环实现批量填充,核心是保存每个Entry的引用,下面是具体解决方案:
关键修改点
- 用字典存储每个属性对应的Entry列表,方便后续按属性名快速获取所有输入框
- 统一循环创建所有属性的LabelFrame和Entry,减少重复代码
- 填充时通过字典取出对应属性的Entry列表,遍历列表逐个赋值
修改后的完整代码
from tkinter import * import random root = Tk() # 存储每个属性的骰子结果 stat_dice = { "Str": [], "Dex": [], "Int": [], "Cons": [], "Wis": [], "Char": [] } # 存储每个属性对应的Entry输入框列表 stat_entries = {} def Roll_Dice(Dice): if Dice == "d6": return [random.randint(1,6) for _ in range(4)] elif Dice == "d20": return random.randint(1,20) def check(name): # 生成并保存骰子结果 stat_dice[name].append(Roll_Dice("d6")) # 禁用对应按钮 buttons[name].config(state="disabled") # 填充输入框 Fill(name, stat_dice[name][0]) def Fill(stat, rolls): # 获取当前属性的所有Entry entries = stat_entries[stat] # 遍历输入框和骰子结果,逐个填充 for entry, roll in zip(entries, rolls): entry.insert(0, str(roll)) # 初始化所有属性的输入框和按钮 Stats = ["Str", "Dex", "Int", "Cons", "Wis", "Char"] buttons = {} # 循环创建每个属性的LabelFrame和Entry for idx, stat in enumerate(Stats): frame = LabelFrame(root, text=stat) frame.place(x=10 + idx*130, y=10) # 存储当前属性的Entry列表 entries_list = [] for row in range(1, 5): entry = Entry(frame) entry.grid(row=row, column=0, pady=5) entries_list.append(entry) stat_entries[stat] = entries_list # 创建按钮框架 STATS = Frame(root) STATS.place(x=10, y=150) # 循环创建每个属性的按钮 for idx, stat in enumerate(Stats): btn = Button(STATS, text=f"Roll for your {stat} stats", command=lambda s=stat: check(s)) btn.grid(row=0, column=idx, padx=2) buttons[stat] = btn root.mainloop()
代码说明
stat_entries字典:键是属性名(如"Str"),值是对应属性下4个Entry的列表,这样就能通过属性名直接获取所有输入框- 统一循环创建UI:用一次循环完成所有属性的LabelFrame和Entry创建,避免重复代码,同时自动把每个Entry加入对应列表
- 填充逻辑优化:
Fill函数通过属性名从字典取出Entry列表,用zip同时遍历输入框和骰子结果,逐个插入数值 - 按钮存储:用
buttons字典保存每个属性的按钮引用,方便在check函数中禁用对应按钮
内容的提问来源于stack exchange,提问作者Deniz -Mëlkor- Durkut
相关产品推荐
相关产品推荐

