python - 在屏幕之间传递值
问题描述
我对kivy完全陌生。该应用程序有两个屏幕 - CalculateScreen 和 ResultScreen。ScreenManager 提供屏幕之间的切换。CalculateScreen 从 TextInput 中获取五个值:start_distance、finish_distance、start_gasoline、added_fuel、normal_consumption。方法计数返回三个值 - day_distance、daily_consumption、gases_left ,必须在按下“计算”按钮时将其传递给 ResultScreen 的适当文本标签: day_distance_result、daily_consumption_result、gass_after_result。我试图通过在更改屏幕时调用 set_values 方法来做到这一点,但它不能以适当的方式工作:
Traceback (most recent call last):
File "mainlogic.py", line 105, in <module>
MyApp().run()
File "C:\Users\Anna\project\lib\site-packages\kivy\app.py", line 950, in run
runTouchApp()
File "C:\Users\Anna\project\lib\site-packages\kivy\base.py", line 582, in runTouchApp
EventLoop.mainloop()
File "C:\Users\Anna\project\lib\site-packages\kivy\base.py", line 347, in mainloop
self.idle()
File "C:\Users\Anna\project\lib\site-packages\kivy\base.py", line 391, in idle
self.dispatch_input()
File "C:\Users\Anna\project\lib\site-packages\kivy\base.py", line 342, in dispatch_input
post_dispatch_input(*pop(0))
File "C:\Users\Anna\project\lib\site-packages\kivy\base.py", line 248, in post_dispatch_input
listener.dispatch('on_motion', etype, me)
File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
File "C:\Users\Anna\project\lib\site-packages\kivy\core\window\__init__.py", line 1412, in on_motion
self.dispatch('on_touch_down', me)
File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
File "C:\Users\Anna\project\lib\site-packages\kivy\core\window\__init__.py", line 1428, in on_touch_down
if w.dispatch('on_touch_down', touch):
File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
File "C:\Users\Anna\project\lib\site-packages\kivy\uix\screenmanager.py", line 1198, in on_touch_down
return super(ScreenManager, self).on_touch_down(touch)
File "C:\Users\Anna\project\lib\site-packages\kivy\uix\widget.py", line 545, in on_touch_down
if child.dispatch('on_touch_down', touch):
File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
File "C:\Users\Anna\project\lib\site-packages\kivy\uix\relativelayout.py", line 297, in on_touch_down
ret = super(RelativeLayout, self).on_touch_down(touch)
File "C:\Users\Anna\project\lib\site-packages\kivy\uix\widget.py", line 545, in on_touch_down
if child.dispatch('on_touch_down', touch):
File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
File "C:\Users\Anna\project\lib\site-packages\kivy\uix\widget.py", line 545, in on_touch_down
if child.dispatch('on_touch_down', touch):
File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
File "C:\Users\Anna\project\lib\site-packages\kivy\uix\behaviors\button.py", line 151, in on_touch_down
self.dispatch('on_press')
File "kivy\_event.pyx", line 705, in kivy._event.EventDispatcher.dispatch
File "kivy\_event.pyx", line 1248, in kivy._event.EventObservers.dispatch
File "kivy\_event.pyx", line 1132, in kivy._event.EventObservers._dispatch
File "C:\Users\Anna\project\lib\site-packages\kivy\lang\builder.py", line 57, in custom_callback
exec(__kvlang__.co_value, idmap)
File "C:\Users\Anna\project\kivy-project\my.kv", line 72, in <module>
on_press: root.set_values()
File "mainlogic.py", line 55, in set_values
result_screen.ids.day_distance_result.text = self.day_distance
AttributeError: 'CalculateScreen' object has no attribute 'day_distance'
这是我的main.py文件。
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.label import Label
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty, StringProperty
class CalculateScreen(Screen):
start_distance = ObjectProperty()
finish_distance = ObjectProperty()
start_gasoline = ObjectProperty()
added_fuel = ObjectProperty()
normal_consumption = ObjectProperty()
def counting(self, start_distance, finish_distance, start_gasoline, added_fuel, normal_consumption):
if self.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))
return day_distance, daily_consumption, 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):
result_screen = self.manager.get_screen("result")
result_screen.ids.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
class ResultScreen(Screen):
day_distance_result = ObjectProperty()
daily_consumption_result = ObjectProperty()
gasoline_after_result = ObjectProperty()
class Manager(ScreenManager):
screen_one = ObjectProperty(None)
screen_two = ObjectProperty(None)
class MyApp(App):
def build(self):
m = Manager()
return m
if __name__=='__main__':
MyApp().run()
这是我的my.kv文件。
<Manager>:
id: screen_manager
screen_one: screen_one
screen_two: screen_two
CalculateScreen:
id: screen_one
name: "calculator"
manager: screen_manager
ResultScreen:
id: screen_two
name: "result"
manager: screen_manager
<CalculateScreen>
name: "calculator"
start_distance: start_distance
finish_distance: finish_distance
start_gasoline: start_gasoline
added_fuel: added_fuel
normal_consumption: normal_consumption
BoxLayout:
orientation: 'vertical'
padding: 20
spacing: 10
BoxLayout:
orientation: 'vertical'
Label:
text: "Start distance"
TextInput:
id: start_distance
BoxLayout:
orientation: 'vertical'
Label:
text: "Final distance"
TextInput:
id: finish_distance
BoxLayout:
orientation: 'vertical'
Label:
text: "Fuel before leaving"
TextInput:
id: start_gasoline
BoxLayout:
orientation: 'vertical'
Label:
text: "Refuelling"
TextInput:
id: added_fuel
BoxLayout:
orientation: 'vertical'
Label:
text: "Normal consumption"
TextInput:
id: normal_consumption
Button:
text:'Calculate'
on_press: root.calculations()
on_press: root.set_values()
on_release: root.manager.current = "result"
<ResultScreen>
name: "result"
on_enter: root.manager.get_screen("calculator").set_values()
day_distance_result: day_distance_result
daily_consumption_result: daily_consumption_result
gasoline_after_result: gasoline_after_result
BoxLayout:
orientation: 'vertical'
padding: 20
spacing: 10
BoxLayout:
Label
text: "Daily distance result"
Label:
text: "0"
id: day_distance_result
BoxLayout:
Label
text: "Daily consumption result"
Label:
text: "0"
id: daily_consumption_result
BoxLayout:
Label
text: "Gasoline after"
Label:
text: "0"
id: gasoline_after_result
BoxLayout:
orientation: 'horizontal'
spacing: 10
Button:
text: 'Exit'
Button:
text: 'Recalculate'
on_release: root.manager.current = "calculator"
解决方案
由于您的set_values()
方法引用了CalculateScreen
实例的属性(如self.day_distance
、self.daily_consumption
等),因此您必须提供这些属性。您可以通过修改您的counting()
方法来设置这些属性来做到这一点:
def counting(self, start_distance, finish_distance, start_gasoline, added_fuel, normal_consumption):
if self.added_fuel == 0:
self.day_distance = str(finish_distance - start_distance)
self.daily_consumption = str((int(self.day_distance) * normal_consumption) / 100)
self.gasoline_left = str(start_gasoline - float(self.daily_consumption))
else:
self.day_distance = str(finish_distance - start_distance)
self.daily_consumption = str((float(self.day_distance) * normal_consumption) / 100)
self.gasoline_left = str((start_gasoline + added_fuel) - float(self.daily_consumption))
# return self.day_distance, self.daily_consumption, self.gasoline_left
请注意,由于未使用返回值,因此可以删除该行。
除非出现异常,否则您的calculations()
方法不会调用该方法。counting()
可能只是一个错字。调用counting()
应该是不缩进的:
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)
另一个问题是文件中Button的on_press
属性。与任何人所期望的完全相反,构造:Calculate
kv
Button:
text:'Calculate'
on_press: root.calculations()
on_press: root.set_values()
on_release: root.manager.current = "result"
结果是root.set_values()
先调用,然后root.calculations()
调用第二。解决方法是只使用一个on_press
属性:
text:'Calculate'
on_press:
root.calculations()
root.set_values()
on_release: root.manager.current = "result"
推荐阅读
- sql - 不明确的列名“Created_Date”?
- ios - ionic Cordova 平台添加 iOS 失败
- java - 通过 JPA 规范加载 Blaze-persistence 实体视图
- node.js - Vercel 构建失败,MERN 堆栈 - @zeit/ncc 模块失败
- r - 如何创建在 R 中给定 group_by 的最大值的新字段?
- javascript - Firebase 存储模拟器不支持 getSignedUrl
- r - 如何仅在此构面环绕中的颜色突出显示点上获得黑色边框
- database - TypeError:无法读取未定义的属性(正在读取“数据库”)
- python - 任务猫抛出“没有合适的分区”错误
- python - 还有一个关于 Flask 的应用程序上下文和 SQLAlchemy 的问题