Kivy使用ScreenManager跨屏幕传值出现AttributeError问题求助
问题根因分析
- 计算结果未保存为实例属性:
counting方法返回的day_distance/daily_consumption/gasoline_left是局部变量,没有赋值给self对应的实例属性,导致set_values调用时找不到对应属性,直接触发AttributeError。
- 计算结果未保存为实例属性:
calculations方法缩进错误:counting的调用逻辑被写在except代码块内,只有输入转换报错时才会执行,正常合法输入场景下根本不会触发计算。
counting方法判断逻辑错误:判断条件写的是self.added_fuel == 0,但self.added_fuel是TextInput组件对象,不是输入的数值,应该用方法入参的added_fuel变量。
- 冗余调用逻辑:KV文件中按钮同时绑定了两次
on_press事件,且ResultScreen的on_enter又重复调用set_values,多次调用容易引发逻辑混乱。
- 冗余调用逻辑:KV文件中按钮同时绑定了两次
- 赋值逻辑不统一:
set_values中对结果标签赋值时,混用了ids访问和直接属性访问,容易因为绑定问题报错。
- 赋值逻辑不统一:
可行修改方案
1. 修改main.py代码
仅需要调整CalculateScreen类的逻辑即可,其余代码保留不变:
class CalculateScreen(Screen): start_distance = ObjectProperty() finish_distance = ObjectProperty() start_gasoline = ObjectProperty() added_fuel = ObjectProperty() normal_consumption = ObjectProperty() # 定义实例属性存储计算结果 day_distance = StringProperty("0") daily_consumption = StringProperty("0") gasoline_left = StringProperty("0") def counting(self, start_distance, finish_distance, start_gasoline, added_fuel, normal_consumption): if added_fuel == 0: day_distance = str(finish_distance-start_distance) daily_consumption = str((int(day_distance)*normal_consumption)/100) gasoline_left = str(start_gasoline-float(daily_consumption)) else: day_distance = str(finish_distance-start_distance) daily_consumption = str((float(day_distance)*normal_consumption)/100) gasoline_left = str((start_gasoline+added_fuel)-float(daily_consumption)) # 将计算结果赋值给实例属性 self.day_distance = day_distance self.daily_consumption = daily_consumption self.gasoline_left = gasoline_left def calculations(self): try: start_distance = float(self.start_distance.text) finish_distance = float(self.finish_distance.text) start_gasoline = float(self.start_gasoline.text) added_fuel = float(self.added_fuel.text) normal_consumption = float(self.normal_consumption.text) except: start_distance = 0 finish_distance = 0 start_gasoline = 0 added_fuel = 0 normal_consumption = 0 # 调整缩进,所有场景下都执行计算 self.counting(start_distance, finish_distance, start_gasoline, added_fuel, normal_consumption) def set_values(self): # 先触发计算逻辑 self.calculations() result_screen = self.manager.get_screen("result") # 统一用绑定好的ObjectProperty赋值 result_screen.day_distance_result.text = self.day_distance result_screen.daily_consumption_result.text = self.daily_consumption result_screen.gasoline_after_result.text = self.gasoline_left
2. 修改my.kv代码
删除冗余调用逻辑,其余布局代码保留不变:
<CalculateScreen> # ... 其余布局代码完全保留 Button: text:'Calculate' # 合并调用逻辑,删除重复的on_press绑定 on_press: root.set_values() on_release: root.manager.current = "result" <ResultScreen> name: "result" # 删除这行冗余的on_enter调用即可,其余代码保留 # on_enter: root.manager.get_screen("calculator").set_values() # ... 其余布局代码完全保留
内容的提问来源于stack exchange,提问作者Анна Мешальникова
相关产品推荐
相关产品推荐

