Tkinter中ComboBox生成输入框后无法填充字典的问题
问题解决:Tkinter输入框值无法存入字典的问题
核心错误分析
- 键类型不匹配:生成
entry1_values/entry2_values时用的是整数键(如0、1),但取值时用了字符串键('0'、'1'),字典匹配键时类型严格一致,导致找不到键。 - 变量名拼写错误:全局变量写成了
slected_number(少了字母e),和函数里的selected_number不统一,导致输入框数量逻辑混乱。 - 全局变量未实时更新:初始的
slected_number只在程序启动时取一次ComboBox的值,ComboBox选择后未同步更新这个变量。 - 冗余的控件销毁逻辑:刚创建空列表就循环销毁,完全起不到清除旧控件的作用,反而会导致后续逻辑异常。
- 值获取方式冗余:已经绑定了
StringVar,没必要用entry.get()覆盖字典里的变量,直接调用StringVar.get()就能拿到最新值。
修正后的完整代码
import tkinter as tk from tkinter import ttk root = tk.Tk() root.title('Rack Position & Injection Volume') root.geometry("700x200") # 全局变量初始化 numbers = [1, 2] combo = ttk.Combobox(root, values=numbers) combo.grid(row=0, column=1) combo.set(numbers[0]) tk.Label(root, text="Select number of plates for this sequence:").grid(column=0, row=0) combo['state'] = 'normal' # 全局变量统一命名,避免拼写错误 selected_number = int(combo.get()) # 保存旧控件的列表,用于销毁 old_entries = [] old_labels = [] old_buttons = [] def generate_entry_boxes(event=None): global selected_number, entry1_values, entry2_values # 先销毁旧控件 for widget in old_entries + old_labels + old_buttons: widget.destroy() old_entries.clear() old_labels.clear() old_buttons.clear() # 更新选中的数量 selected_number = int(combo.get()) entry1_values = {} # 存位置的StringVar,键为整数0、1 entry2_values = {} # 存体积的StringVar,键为整数0、1 for i in range(selected_number): # 创建位置输入框和变量 pos_var = tk.StringVar() entry1 = ttk.Entry(root, textvariable=pos_var) entry1.grid(row=i+1, column=1) entry1_values[i] = pos_var old_entries.append(entry1) # 创建体积输入框和变量 vol_var = tk.StringVar() entry2 = ttk.Entry(root, textvariable=vol_var) entry2.grid(row=i+1, column=3) entry2_values[i] = vol_var old_entries.append(entry2) # 创建标签 pos_label = ttk.Label(root, text=f"Position of plate {i+1}:") pos_label.grid(row=i+1, column=0) old_labels.append(pos_label) vol_label = ttk.Label(root, text="Injection Volume(uL):") vol_label.grid(row=i+1, column=2) old_labels.append(vol_label) # 只创建一个提交按钮 submit_btn = tk.Button(root, text="Submit", command=get_entries) submit_btn.grid(row=selected_number + 1, column=1) old_buttons.append(submit_btn) def get_entries(): # 用整数键取值,直接调用StringVar的get()方法 entry_plate1 = entry1_values.get(0, 'Key not found') if entry_plate1 != 'Key not found': entry_plate1 = entry_plate1.get() entry_plate2 = entry1_values.get(1, 'Key not found') if entry_plate2 != 'Key not found': entry_plate2 = entry_plate2.get() entry_vol1 = entry2_values.get(0, 'Key not found') if entry_vol1 != 'Key not found': entry_vol1 = entry_vol1.get() entry_vol2 = entry2_values.get(1, 'Key not found') if entry_vol2 != 'Key not found': entry_vol2 = entry_vol2.get() # 测试输出,确认取值成功 print(f"Plate1 Position: {entry_plate1}") print(f"Plate2 Position: {entry_plate2}") print(f"Volume1: {entry_vol1}") print(f"Volume2: {entry_vol2}") # 以下是原代码中的DataFrame操作,需确保df已定义 # condition_mask = df['Vial Position'] == 1 # second_occurrence_index = df[condition_mask].index[1] # after_mask = df.index >= second_occurrence_index # df.loc[~after_mask, 'Rack Position'] = entry_plate1 # df.loc[after_mask, 'Rack Position'] = entry_plate2 # df['Plate Position'] = df['Rack Position'] # df.loc[~after_mask, 'Injection Volume'] = entry_vol1 # df.loc[after_mask, 'Injection Volume'] = entry_vol2 # 绑定ComboBox选择事件 combo.bind("<<ComboboxSelected>>", generate_entry_boxes) # 初始化生成输入框 generate_entry_boxes() root.mainloop()
关键修复点说明
- 统一键类型:取值时用整数键
0、1替代字符串键,和字典创建时的键类型保持一致。 - 修正变量名拼写:把
slected_number改为selected_number,确保全局变量名统一。 - 实时更新选中数量:在
generate_entry_boxes函数开头重新获取ComboBox的选中值,更新全局变量。 - 优化控件销毁逻辑:用专门的列表保存旧控件,每次生成新控件前统一销毁,避免界面残留。
- 正确获取StringVar的值:直接调用
StringVar.get()方法获取输入框内容,无需覆盖字典中的变量。
内容的提问来源于stack exchange,提问作者PyGuy2000
相关产品推荐
相关产品推荐

