Python Tkinter进度条开发触发NoneType与int运算TypeError问题求解
错误触发原因
- 核心原因是你定义的
num函数在now=86/93的场景下没有执行任何return语句,默认返回None,后续执行num(101)/10时就会触发「NoneType和int不能做除法」的报错。 - 具体触发逻辑:
- 代码里
first固定为100,achieve固定为75,二者差值为25,计算y=(first-achieve)*(z/100)时用了浮点数运算,判断(first-today)==y用的是精确相等判断,浮点数精度误差会导致部分理论上相等的值被判为不相等:比如now=86时,理论上z=56时y=14刚好等于100-86=14,但浮点数运算可能得到13.999999999999998或者14.000000000000002,无法命中相等条件。 - 当
now大于等于achieve时,第二个if分支if today<achieve永远不会触发,循环遍历完所有z值都没有命中任何return逻辑,函数就会默认返回None。
- 代码里
- 只有
now为86、93时会触发报错,是因为其余now值对应的z值计算时刚好没有浮点数精度误差,可以命中相等条件返回正确值。
解决方法
你可以从两个维度修复问题,避免无返回值的情况:
- 把浮点数相等判断改成整数运算,彻底避免精度问题,将判断条件替换为全程整数运算的逻辑:
if (first - today) * 100 == (first - achieve) * z:
- 给
num函数加兜底返回值,避免遍历完所有值都没有返回的情况,在num函数的for循环结束后,根据业务逻辑加默认返回即可。
优化后完整可运行代码示例:
from tkinter import * app=Tk() app.title("progress") app.geometry("800x500+365+120") q={'weigh':100,'goal':75,'now':86} # 测试now=86/93都不会报错 def bar(): first=int(q['weigh']) achieve=int(q['goal']) today=int(q['now']) def num(n): for z in range(0,n): # 改用整数运算避免浮点数精度问题 if (first - today) * 100 == (first - achieve) * z: return z if today < achieve: return 100 # 兜底返回最接近的进度值 return round((first - today) * 100 / (first - achieve)) rate=int(num(101)/10) for _ in range(1,rate+1): Entry(app,bg="blue",width=4).pack(side=LEFT) for _ in range(rate,10): Entry(app,width=4).pack(side=LEFT) Button(app,text="OK",command=bar).pack() app.mainloop()
内容的提问来源于stack exchange,提问作者Kim minseong
相关产品推荐
相关产品推荐

