Tkinter中如何获取嵌套绑定Combobox的选中值?
解决Tkinter嵌套Combobox选中值无法外部获取的问题
问题分析
你遇到的问题是:Queue_Combo、MT_Combo、Merge_Combo这些动态显示的Combobox,在LSF_Fields_Enable函数外部调用get()无法获取选中值,而LSF_Combo可以正常获取。核心原因是动态布局的组件直接调用get()可能受组件显示状态影响,通过绑定StringVar变量可以更稳定地追踪选中值。
解决方案
使用tk.StringVar为每个Combobox绑定值变量,通过变量的get()方法获取选中值,不受组件显示状态影响。具体修改如下:
- 为每个Combobox创建对应的
StringVar变量 - 将变量绑定到Combobox的
textvariable参数 - 在任意作用域通过变量的
get()获取选中值
修改后的完整代码
from tkinter import * import tkinter as tk from tkinter import ttk root = Tk() root.geometry("800x450") def Gui_main(): # 为每个Combobox创建绑定变量 queue_var = tk.StringVar() merge_var = tk.StringVar() mt_var = tk.StringVar() lsf_var = tk.StringVar() Queue_Combo_list = ['normal', 'priority', 'devices', 'grid'] Queue_Combo = ttk.Combobox(root, values=Queue_Combo_list, width=10, state="readonly", textvariable=queue_var) Merge_Combo_list = ['LST_SET_ML', 'LST_SET_EQU'] Merge_Combo = ttk.Combobox(root, values=Merge_Combo_list, width=12, textvariable=merge_var) MT_Combo_list = ['MT', 'MTFLEX'] MT_Combo = ttk.Combobox(root, values=MT_Combo_list, width=10, textvariable=mt_var) def LSF_Fields_Enable(event): if lsf_var.get() == 'LSF': # Queue相关布局 Queue_Combo_label = tk.Label(root, text="Queue: ").grid(row=2, column=1, padx=5, sticky=W) queue_var.set("normal") # 通过变量设置初始值 Queue_Combo.grid(row=2, column=1, padx=55, pady=5, sticky=W) def MT_MT_flex(choice): def Manage_run_mode(choice): if merge_var.get() != 'LSF_SET_ML': label = tk.Label(root, text="CPU No:").grid(row=4, column=3, padx=10, sticky=tk.W) CPU_radio_button = tk.IntVar() R1 = Radiobutton(root, text="2", variable=CPU_radio_button, value=1).place(x=50, y=120) # 修正y坐标避免超出窗口 if mt_var.get() == 'MT': # Merge相关布局 Merge_Combo_label = tk.Label(root, text="Merge: ").grid(row=6, column=2, padx=10, sticky=W) merge_var.set("LST_SET_ML") # 通过变量设置初始值 Merge_Combo.grid(row=6, column=2, padx=65, pady=15, sticky=tk.E) Merge_Combo.bind('<<ComboboxSelected>>', Manage_run_mode) # MT相关布局 MT_Combo_label = tk.Label(root, text="MT/MTflex: ").grid(row=2, column=3, padx=10, sticky=W) mt_var.set("MT") # 通过变量设置初始值 MT_Combo.grid(row=2, column=4, padx=5, pady=5, sticky=tk.E) MT_Combo.bind('<<ComboboxSelected>>', MT_MT_flex) else: # 切换到LOCAL时隐藏动态组件 Queue_Combo.grid_remove() MT_Combo.grid_remove() Merge_Combo.grid_remove() # LSF Combo布局 LSF_Combo_label = tk.Label(root, text="Fill: ").grid(row=2, column=0, sticky=W) LSF_Combo_list = ['LSF', 'LOCAL'] LSF_Combo = ttk.Combobox(root, values=LSF_Combo_list, width=10, state="readonly", background='white', textvariable=lsf_var) lsf_var.set('LSF') LSF_Combo.grid(row=2, column=0, padx=25, pady=5, sticky=W) LSF_Combo.bind('<<ComboboxSelected>>', LSF_Fields_Enable) # 绑定选中事件(可选,用于测试) Queue_Combo.bind('<<ComboboxSelected>>', lambda _: print(queue_var.get())) MT_Combo.bind('<<ComboboxSelected>>', lambda _: print(mt_var.get())) Merge_Combo.bind('<<ComboboxSelected>>', lambda _: print(merge_var.get())) def run_program(): a = lsf_var.get() print(f"LSF值: {a}") b = queue_var.get() print(f"Queue值: {b}") c = mt_var.get() print(f"MT值: {c}") d = merge_var.get() print(f"Merge值: {d}") # 这里可以直接使用这些变量进行后续操作 # 按钮布局 close = Button(root, text='close', command=root.destroy).grid(row=10, column=2, pady=60, sticky=E) check_combo_get = Button(root, text='check_combo_get', command=run_program).grid(row=10, column=1, padx=15, pady=60, sticky=E) # 初始化时调用一次LSF_Fields_Enable显示默认组件 LSF_Fields_Enable(None) root.mainloop() if __name__ == "__main__": Gui_main()
关键修改说明
- 绑定StringVar:为每个Combobox创建对应的
StringVar,并通过textvariable参数绑定,组件的选中值会自动同步到变量中。 - 通过变量设置/获取值:设置初始值时使用
变量.set(),获取值时使用变量.get(),替代组件的set()和get()方法,确保在任意作用域都能稳定获取值。 - 隐藏组件处理:新增
else分支,当LSF_Combo切换到LOCAL时,调用grid_remove()隐藏动态组件,避免界面混乱。 - 初始化显示:在
Gui_main末尾调用LSF_Fields_Enable(None),确保程序启动时默认显示LSF对应的组件。
现在点击check_combo_get按钮,就能在run_program中正确获取所有Combobox的选中值,比如选中Queue_Combo的priority、MT_Combo的MT时,变量b和c会对应这些值。
内容的提问来源于stack exchange,提问作者Jay
相关产品推荐
相关产品推荐

