Tkinter中temperatureA无法从下拉框取值的技术问题
问题:无法从Tkinter下拉框(Combobox)获取值
代码中第56行的temperatureA = watertemperature.get()无法从watertemperature下拉菜单获取选中值,但手动赋值(比如temperatureA = "40")时后续代码能正常运行,请问原因是什么?
相关代码:
import tkinter from tkinter import messagebox, ttk from tkinter import ttk # set root root = tkinter.Tk() root = tkinter.Tk() root.geometry("270x150") a = tkinter.Label(root, text="Technology") a.grid(row=1, column=1, columnspan=2, padx=10, pady=2, sticky='w') # grid X1 = ["18.3", "4.7", "15.9", "5.5", "50"] X2 = ["74", "5.8", "21.1", "6.56", "50"] X3 = ["28.7", "7.5", "29.3", "8.5", "50"] X4 = ["41", "9.4", "23", "10.3", "40"] X5 = ["44.7", "11.8", "45.2", "13.4", "50"] X6 = ["78", "11.8", "48.7", "11.9", "35"] units = [X1 + X2 + X3 + X4 + X5 + X6] type = ["Heat Pumps", "Heat Interface Units", "District Heat Networks", "photovotaic panels"] watertemp = [["35", "40", "45", "50", "55", "60", "65"], ["44", "22", "14", "75"], ["12", "28", "15"], ["25", "42", "91"]] techtype = ttk.Combobox(root, width=37, value=(type)) techtype.grid(row=3, column=1, columnspan=2, padx=10, pady=2, sticky='w') def callback(eventObject): abc = eventObject.widget.get() water = techtype.get() index = type.index(water) watertemperature.config(values=watertemp[index]) temperatureA = watertemperature.get() print(temperatureA) # Find value from index location temperature = [item[4] for item in units] # Find value index degreesindex = [i for i in range(len(temperature)) if temperature[i] == temperatureA] # Creates list from temperature res_list = [units[i] for i in degreesindex] # Find the heating load duty = [item[0] for item in res_list] print(duty) watertemperature = ttk.Combobox(root, width=37, value=watertemp) watertemperature.grid(row=4, column=1, columnspan=2, padx=10, pady=2, sticky='w') watertemperature.bind('<Button-1>', callback) root.mainloop()
问题原因
- 绑定事件时机错误:给
watertemperature绑定了<Button-1>(左键点击)事件,这个事件在用户刚点击下拉框、还没选择任何选项时就触发,此时下拉框没有选中值,自然拿不到内容。 - 逻辑顺序混乱:在
callback里刚更新完watertemperature的选项列表,立刻调用get(),但用户还没来得及选择新选项,获取的要么是空值,要么是旧值。 - 初始化参数错误:
watertemperature初始化时value=watertemp,但watertemp是二维列表,不符合Combobox的value参数要求(需为一维列表),导致初始状态下拉框没有正确选项。
解决方案
1. 调整事件绑定
把watertemperature的绑定事件改成<<ComboboxSelected>>,这个事件仅在用户选中下拉框选项后触发,能确保拿到有效选中值。同时给techtype绑定该事件,用来更新watertemperature的选项列表。
2. 拆分逻辑
把“更新水温选项”和“计算负载”的逻辑分开:
- 用户选择技术类型时,仅更新
watertemperature的可选值; - 用户选择水温后,再执行后续计算逻辑。
3. 修正初始化
watertemperature初始时设置value=watertemp[0](默认显示第一个技术类型的水温选项),或者先设为空,等用户选技术类型再更新。
修改后的代码
import tkinter from tkinter import ttk root = tkinter.Tk() root.geometry("270x150") a = tkinter.Label(root, text="Technology") a.grid(row=1, column=1, columnspan=2, padx=10, pady=2, sticky='w') X1 = ["18.3", "4.7", "15.9", "5.5", "50"] X2 = ["74", "5.8", "21.1", "6.56", "50"] X3 = ["28.7", "7.5", "29.3", "8.5", "50"] X4 = ["41", "9.4", "23", "10.3", "40"] X5 = ["44.7", "11.8", "45.2", "13.4", "50"] X6 = ["78", "11.8", "48.7", "11.9", "35"] # 修正:每个X列表作为单独元素,避免后续索引错误 units = [X1, X2, X3, X4, X5, X6] # 避免使用Python内置关键字type,修正拼写错误 tech_types = ["Heat Pumps", "Heat Interface Units", "District Heat Networks", "photovoltaic panels"] watertemp_options = [ ["35", "40", "45", "50", "55", "60", "65"], ["44", "22", "14", "75"], ["12", "28", "15"], ["25", "42", "91"] ] # 技术类型下拉框 techtype = ttk.Combobox(root, width=37, value=tech_types) techtype.grid(row=3, column=1, columnspan=2, padx=10, pady=2, sticky='w') # 水温下拉框:初始显示第一个技术类型的水温选项 watertemperature = ttk.Combobox(root, width=37, value=watertemp_options[0]) watertemperature.grid(row=4, column=1, columnspan=2, padx=10, pady=2, sticky='w') def update_watertemp_options(event): # 选择技术类型时更新水温选项 selected_tech = techtype.get() if selected_tech in tech_types: index = tech_types.index(selected_tech) watertemperature.config(values=watertemp_options[index]) watertemperature.set('') # 清空之前的选择 def calculate_load(event): # 选择水温后执行计算逻辑 temperatureA = watertemperature.get() if not temperatureA: return # 未选水温直接返回 print(f"选中的水温:{temperatureA}") # 提取每个units元素的第4个值(索引4) temperature_list = [item[4] for item in units] # 找到匹配的索引 degreesindex = [i for i, temp in enumerate(temperature_list) if temp == temperatureA] # 筛选对应的units元素 res_list = [units[i] for i in degreesindex] # 提取加热负载 duty = [item[0] for item in res_list] print(f"计算得到的负载:{duty}") # 绑定正确的事件 techtype.bind('<<ComboboxSelected>>', update_watertemp_options) watertemperature.bind('<<ComboboxSelected>>', calculate_load) root.mainloop()
内容的提问来源于stack exchange,提问作者James Knight
相关产品推荐
相关产品推荐

