Tkinter GUI满足条件后无法显示计算数值问题求助
Tkinter飞船参数计算程序:结果标签未显示问题
我正在开发一款基于Tkinter的UI程序,用于根据用户输入计算并展示飞船规格参数(如加速度)。程序运行无报错,但当所有条件满足时,本该显示在“Ship Specifications:”下方的结果标签却未出现。相关代码如下:
from tkinter import * from tkinter import ttk window = Tk() window.title("Specifications Calculations") window.geometry('600x4000') frameprimaire = Frame(window) frameprimaire.pack(fill = BOTH, expand = 1) Cannavar = Canvas(frameprimaire) Cannavar.pack(side = LEFT, fill = BOTH, expand = 1) CannavarFrame = Frame(Cannavar) Cannavar.create_window((0,0), window = CannavarFrame, anchor = "nw") # Relevant Vars, Tuples, and Dicts LargeHydro = (7200000, 4820, 7.5) Tiers = ("Base") Sizes = ("Large") Types = ("Hydrogen") ThrusterStatsLarge = { "HBase":LargeHydro, } # Relevant function 2, is used to create the final value def speedcalc(weight, number, size, tier, type): InformationPackage = {} # Assembly is meant to produce a string that corresponds with a key in either ThrusterStatsLarge # or ThrusterStatsSmall; ex. Assembly = "HT2". Assembly = "" Assembly + type[0] Assembly + tier if size == "Large": for key, entry in ThrusterStatsLarge.items(): if key == Assembly: # Infoset is a temporary storage of the relevant stats InfoSet = entry else: pass elif size == "Small": for key, entry in ThrusterStatsSmall.items(): if key == Assembly: InfoSet = entry else: pass InformationPackage["Acceleration"] = (InfoSet[0] * number)/weight return InformationPackage # Program kept returning the error "expected float, got '!text'"; this stopped that error. if (TopEngines.get() and TopSize.get()) and (TopTier.get() and TopType.get()): Top = True else: Top = False # Finally, a section of code that demonstrates the issue. SpecificationsLabel = Label(CannavarFrame, text = "Ship Specifications:") SpecificationsLabel.pack(side = RIGHT) ShipWeightLabel = Label(CannavarFrame, text = "Enter ship weight.") SWT = Text(CannavarFrame, height = 1, width = 30) ShipWeight.set(SWT) ShipWeightLabel.pack(side = TOP) SWT.pack(side = TOP) TopThrusterLabel = Label(CannavarFrame, text = "Enter amount of top thrusters.") TTDM = OptionMenu(CannavarFrame, TopSize, *Sizes) TTTDM = OptionMenu(CannavarFrame, TopTier, *Tiers) TTETDM = OptionMenu(CannavarFrame, TopType, *Types) TTN = Text(CannavarFrame, height = 1, width = 5) TopEngines.set(TTN) TopThrusterLabel.pack(side = TOP) TTDM.pack(side = TOP) TTTDM.pack(side = TOP) TTETDM.pack(side = TOP) TTN.pack(side = TOP) if Top: # TopAcceleration should show up below SpecificationsLabel; however, it does not. TopThrusterInformation = speedcalc(ShipWeight.get(), TopEngines.get(), TopSize.get(), TopTier.get(), TopType.get()) TopAcceleration = Label(CannavarFrame, text = f"Top Acceleration: {TopThrusterInformation[0]}") TopAcceleration.pack(side = RIGHT) else: pass window.mainloop()
问题根源及修复步骤
1. 执行时机错误
程序启动时就执行了Top的判断逻辑,此时用户还未输入任何内容,Top必然为False,结果标签根本不会被创建。必须把计算和显示逻辑放到用户触发的事件中(比如按钮点击),确保用户输入后才执行计算。
2. Tkinter变量未初始化
代码中使用的TopEngines、TopSize、TopTier、TopType、ShipWeight都是Tkinter的变量类型,需要先通过StringVar()或IntVar()初始化,否则无法正常使用get()和set()方法。
3. Text组件取值错误
Text组件不能直接用get()取值,正确写法是get("1.0", END).strip(),同时不能把组件对象赋值给变量(比如ShipWeight.set(SWT)),应该直接从组件获取输入内容。
4. 字符串拼接错误
speedcalc函数中Assembly的拼接方式错误,Assembly + type[0]不会修改原变量,必须用Assembly += type[0]才能完成拼接,否则Assembly为空字符串,无法匹配字典中的键。
5. 字典取值错误
speedcalc返回的是字典,需要通过键名"Acceleration"访问,而不是索引[0]。
修正后的完整代码
from tkinter import * from tkinter import ttk window = Tk() window.title("Specifications Calculations") window.geometry('600x400') frameprimaire = Frame(window) frameprimaire.pack(fill=BOTH, expand=1) Cannavar = Canvas(frameprimaire) Cannavar.pack(side=LEFT, fill=BOTH, expand=1) CannavarFrame = Frame(Cannavar) Cannavar.create_window((0,0), window=CannavarFrame, anchor="nw") # 初始化Tkinter变量 TopSize = StringVar(value="Large") TopTier = StringVar(value="Base") TopType = StringVar(value="Hydrogen") # 定义参数数据 LargeHydro = (7200000, 4820, 7.5) ThrusterStatsLarge = {"HBase": LargeHydro} def speedcalc(weight, number, size, tier, type): InformationPackage = {} # 正确拼接字典键 Assembly = type[0] + tier InfoSet = None if size == "Large": InfoSet = ThrusterStatsLarge.get(Assembly) # 这里可以补充Small类型的逻辑 if InfoSet: InformationPackage["Acceleration"] = (InfoSet[0] * number) / weight return InformationPackage def calculate_specs(): # 清空之前的结果标签 for widget in CannavarFrame.winfo_children(): if widget.winfo_class() == 'Label' and "Top Acceleration" in widget['text']: widget.destroy() # 获取用户输入 try: ship_weight = float(SWT.get("1.0", END).strip()) top_engine_count = int(TTN.get("1.0", END).strip()) size = TopSize.get() tier = TopTier.get() type = TopType.get() # 调用计算函数 info = speedcalc(ship_weight, top_engine_count, size, tier, type) if "Acceleration" in info: # 创建并显示结果标签 TopAcceleration = Label(CannavarFrame, text=f"Top Acceleration: {info['Acceleration']:.2f}") TopAcceleration.pack(side=TOP, anchor=E) except ValueError: # 处理输入非数字的情况 error_label = Label(CannavarFrame, text="请输入有效的数字", fg="red") error_label.pack(side=TOP, anchor=E) # UI布局 SpecificationsLabel = Label(CannavarFrame, text="Ship Specifications:") SpecificationsLabel.pack(side=TOP, anchor=E) # 飞船重量输入 ShipWeightLabel = Label(CannavarFrame, text="Enter ship weight.") SWT = Text(CannavarFrame, height=1, width=30) ShipWeightLabel.pack(side=TOP, anchor=W) SWT.pack(side=TOP, fill=X) # 推进器参数输入 TopThrusterLabel = Label(CannavarFrame, text="Enter amount of top thrusters.") TTDM = OptionMenu(CannavarFrame, TopSize, "Large") TTTDM = OptionMenu(CannavarFrame, TopTier, "Base") TTETDM = OptionMenu(CannavarFrame, TopType, "Hydrogen") TTN = Text(CannavarFrame, height=1, width=5) TopThrusterLabel.pack(side=TOP, anchor=W) TTDM.pack(side=TOP, anchor=W) TTTDM.pack(side=TOP, anchor=W) TTETDM.pack(side=TOP, anchor=W) TTN.pack(side=TOP, anchor=W) # 添加计算按钮 calc_btn = Button(CannavarFrame, text="Calculate", command=calculate_specs) calc_btn.pack(side=TOP, pady=10) window.mainloop()
内容的提问来源于stack exchange,提问作者RousseDusk
相关产品推荐
相关产品推荐

