Tkinter程序报错:str与float无法执行**运算,求问题排查
问题分析与修复方案
首先看你碰到的这个错误:TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'float',根源其实出在**change()函数里获取输入值的时机不对,而且没做类型转换**。
错误具体原因
在你的change()函数里,创建完输入框后立刻就执行了dp1=dp.get()和d1=d.get():
dp=Tk.StringVar() dp=ttk.Entry(updateFrame, width=20) dp.grid(column=1, row=0) d=Tk.StringVar() d=ttk.Entry(updateFrame, width=20) d.grid(column=1, row=1) dp1=dp.get() d1=d.get()
这时候用户还没在输入框里输入任何内容,dp.get()和d.get()拿到的是空字符串"";就算之后用户输入了数值,dp1和d1也不会自动更新——因为你只获取了一次初始值。最后把这个字符串传给update()函数,在db=m.ceil(0.65*(((d**3.0)*(T+160))/(i*D*Tb))**0.5)这一行里,字符串和浮点数做幂运算,自然就触发了类型错误。
修复步骤
1. 修正change()函数的按钮回调逻辑
别提前获取输入值,改成在用户点击Update按钮时,实时抓取输入框内容并转成浮点数,再传给update()函数:
def change(): # Customer Changes Frame updateFrame=ttk.LabelFrame(win,text="Changes") updateFrame.grid(column=0,row=12) changelabel=("Diameter of Tailshaft (mm)","Diameter of Intermediate shaft (mm)") for b in range (0,2): ttk.Label(updateFrame,text=changelabel[b]).grid(column=0, row=b, pady=5) # 这里不需要额外定义StringVar,直接用Entry组件即可 dp=ttk.Entry(updateFrame, width=20) dp.grid(column=1, row=0) d=ttk.Entry(updateFrame, width=20) d.grid(column=1, row=1) # 单独写一个点击回调函数,实时处理输入 def on_update(): try: # 把用户输入的字符串转成浮点数 dp_val = float(dp.get()) d_val = float(d.get()) update(dp_val, d_val) except ValueError: # 处理用户输入非数字的情况 print("请输入有效的数字!") enter2=ttk.Button(updateFrame, text="Update", command=on_update) enter2.grid(column=1, row=2, pady=10)
2. 修复输出面板的未定义变量问题
原代码里定义output=(dp,d,db,t,l,Ak)时,这些变量还没被初始化,会触发NameError。可以把输出标签的更新逻辑移到update()函数里,让计算完成后自动刷新界面:
# 先初始化输出标签,保存到列表方便后续更新 outputFrame=ttk.LabelFrame(win,text="Output") outputFrame.grid(column=2,row=0) outputlabel=("Diameter of Tailshaft (mm)=","Diameter of Intermediate shaft (mm) =","Diameter of bolt (mm) =","Thickness of liner (mm) =","Sternbush bearing length (mm) =","Cross-sectional Area of keyway (mm^2) =") output_labels = [] for a in range (0,6): ttk.Label(outputFrame,text=outputlabel[a]).grid(column=0, row=a, padx=20) # 创建空的输出标签并保存 lbl = ttk.Label(outputFrame, text="") lbl.grid(column=1, row=a, padx=20) output_labels.append(lbl) # 修改update函数,添加更新输出标签的逻辑 def update(dp,d): T=float(T1.get()) Tb=float(Tb1.get()) i=float(i1.get()) D=float(D1.get()) # bolt dia if "Sea" in (water1.get()): db=m.ceil(0.65*(((d**3.0)*(T+160))/(i*D*Tb))**0.5) else: db=m.ceil(((0.427*(d**3.0)*(T+155))/(i*D*Tb))**0.5) # liner thickness t=m.ceil((168+dp)/28) # bush length if "Water" in (lub1.get()): l=m.ceil(4*dp) else: l=m.ceil(2*dp) # c/s area of key Ak=m.ceil((d**3)/(2.6*d)) print(dp,d,db,Ak,l,t) # 更新输出面板的内容 output_values = (dp, d, db, t, l, Ak) for idx, lbl in enumerate(output_labels): lbl.config(text=str(output_values[idx]))
测试验证
修改后,点击Calculate按钮能正常计算并显示结果;打开Changes面板输入数值后点击Update,就能正确传递数值类型的参数给update()函数,不会再触发类型错误,同时输出面板的内容也会实时刷新。
内容的提问来源于stack exchange,提问作者Mayur Shevate
相关产品推荐
相关产品推荐

