如何获取、使用和更改 .kv 文件中的值
How to get, use and change values from a .kv file
所以,我一直在开发一个非常简单的 kivy 应用程序,但遇到了后端问题。您将如何从 text_input 获取值并更改标签值?我看过一些教程,但它们的方法各不相同,而且我收到错误消息。
这是我的 python 代码:
import kivy
from kivy.app import App
kivy.require('1.9.1')
class MyWindowApp(App):
pass
window = MyWindowApp()
window.run()
这是 .kv 文件:
Screen:
side: side
FloatLayout:
Label:
text: "Side:"
pos_hint: {"x": 0.1, "y": 0.7}
text_size: self.size
Label:
text: "Volume:"
pos_hint: {"x": 0.1, "y": 0.65}
text_size: self.size
Label:
text: "Surface Area:"
pos_hint: {"x": 0.1, "y": 0.6}
text_size: self.size
TextInput:
size_hint: (.4, None)
height: 26
multiline: False
pos_hint: {"x": 0.24, "y": 0.7}
id: side
Label:
text: "0cm"
id: volume
pos_hint: {"x": 0.27, "y": 0.65}
text_size: self.size
Label:
text: "0cm"
id: surface_area
pos_hint: {"x": 0.355, "y": 0.6}
text_size: self.size
为什么你的 App class 中没有构建方法?
试试这个:
import kivy
from kivy.app import App
from kivy.lang.builder import Builder
kivy.require('1.9.1')
class MyWindowApp(App):
def build(self):
self.root = Builder.load_file("YOUR_KV_FILE.kv")
return self.root
window = MyWindowApp()
window.run()
别忘了把YOUR_KV_FILE.kv改成你自己的kv文件名
因为你没有使用 Builder.load_file 方法来加载你的 kv 文件,你的 kv 文件名必须类似于 mywindow.kv 但我建议使用 Builder.load_file 因为你可以保存整个 window 在一个变量中,以后可以轻松访问它,它还可以让您自由更改您的 kv 设计文件名
如其他答案中所述,将 Builder.load_file
或 Builder.load_string
放入您的 build
方法中。
处理变化,例如如果用户在侧面输入中点击回车,使用 on_text_validate: app.on_side_change(self)
或放置一个按钮来触发计算并使用 on_press
方法。
您的 class MyApp
中的 on_side_change
方法将处理更改。一旦用户点击回车,它就会被调用。有关基本计算,请参阅下面的示例代码。
对于 labels/inputs 中的 getting/setting 值,您可以使用 kivy.properties
中的 ObjectProperty
或 StringProperty
。在下面的代码中,我使用了 StringProperty
。
重要的是,您需要在您的应用 class 中使用 StringProperty
并在 kv 文件中使用它。
对于你计算的mode
,我添加了一个属性,所以你可以在你的计算方法中使用它。
mode
也用于 kv 文件中,因此它显示当前模式。
switcher
字典是 Python 执行 switch/case 语句的方法。
示例代码
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import StringProperty
kv = """
Screen:
side: side
GridLayout:
rows: 1
cols:2
spacing:0
GridLayout:
rows: 5
cols:1
Button:
text: "Cube"
# on_press: app.mode = self.text
on_press: app.setMode(self)
Button:
text: "Cuboid"
on_press: app.setMode(self)
Button:
text: "Cylinder"
on_press: app.setMode(self)
Button:
text: "Cone"
on_press: app.setMode(self)
Button:
text: "Sphere"
on_press: app.setMode(self)
FloatLayout:
Label:
text: "The Volume and surface area of a {}:".format(app.mode)
pos_hint: {"x":0.1, "y":0.8}
text_size: self.size
Label:
text:"Side:"
pos_hint: {"x":0.1, "y":0.7}
text_size: self.size
Label:
text:"Volume:"
pos_hint: {"x":0.1, "y":0.65}
text_size: self.size
Label:
text:"Surface Area:"
pos_hint: {"x":0.1, "y":0.6}
text_size: self.size
TextInput:
size_hint: (.4, None)
height: 26
multiline: False
pos_hint: {"x":0.24, "y":0.7}
id: side
text: app.sideText
on_text_validate: app.on_side_change(self)
Label:
text: app.volume
pos_hint: {"x":0.27, "y":0.65}
text_size: self.size
Label:
text: app.area
pos_hint: {"x":0.355, "y":0.6}
text_size: self.size
"""
class MyApp(App):
sideText = StringProperty("")
area = StringProperty("0 cm²")
volume = StringProperty("0 cm³")
mode = StringProperty("Cube")
def build(self):
return Builder.load_string(kv)
def setMode(self, btn):
self.mode = btn.text
def on_side_change(self, instance):
print(instance.text)
result = 0
try:
value = float(instance.text)
except:
# failed to convert
return
def cubeCalc(val):
return {
"volume": val * val * val,
"area": val * val
}
switcher = {
"Cube": cubeCalc
}
method = switcher.get(self.mode, "Unknown mode")
if method is not "Unknown mode":
result = method(value) # result is a dictionary with volume & area
#print(result)
print(self.volume)
self.volume = "{:.2f} cm³".format(result["volume"])
self.area = "{:.2f} cm²".format(result["area"])
if __name__ == "__main__":
MyApp().run()
所以,我一直在开发一个非常简单的 kivy 应用程序,但遇到了后端问题。您将如何从 text_input 获取值并更改标签值?我看过一些教程,但它们的方法各不相同,而且我收到错误消息。 这是我的 python 代码:
import kivy
from kivy.app import App
kivy.require('1.9.1')
class MyWindowApp(App):
pass
window = MyWindowApp()
window.run()
这是 .kv 文件:
Screen:
side: side
FloatLayout:
Label:
text: "Side:"
pos_hint: {"x": 0.1, "y": 0.7}
text_size: self.size
Label:
text: "Volume:"
pos_hint: {"x": 0.1, "y": 0.65}
text_size: self.size
Label:
text: "Surface Area:"
pos_hint: {"x": 0.1, "y": 0.6}
text_size: self.size
TextInput:
size_hint: (.4, None)
height: 26
multiline: False
pos_hint: {"x": 0.24, "y": 0.7}
id: side
Label:
text: "0cm"
id: volume
pos_hint: {"x": 0.27, "y": 0.65}
text_size: self.size
Label:
text: "0cm"
id: surface_area
pos_hint: {"x": 0.355, "y": 0.6}
text_size: self.size
为什么你的 App class 中没有构建方法? 试试这个:
import kivy
from kivy.app import App
from kivy.lang.builder import Builder
kivy.require('1.9.1')
class MyWindowApp(App):
def build(self):
self.root = Builder.load_file("YOUR_KV_FILE.kv")
return self.root
window = MyWindowApp()
window.run()
别忘了把YOUR_KV_FILE.kv改成你自己的kv文件名
因为你没有使用 Builder.load_file 方法来加载你的 kv 文件,你的 kv 文件名必须类似于 mywindow.kv 但我建议使用 Builder.load_file 因为你可以保存整个 window 在一个变量中,以后可以轻松访问它,它还可以让您自由更改您的 kv 设计文件名
如其他答案中所述,将 Builder.load_file
或 Builder.load_string
放入您的 build
方法中。
处理变化,例如如果用户在侧面输入中点击回车,使用 on_text_validate: app.on_side_change(self)
或放置一个按钮来触发计算并使用 on_press
方法。
您的 class MyApp
中的 on_side_change
方法将处理更改。一旦用户点击回车,它就会被调用。有关基本计算,请参阅下面的示例代码。
对于 labels/inputs 中的 getting/setting 值,您可以使用 kivy.properties
中的 ObjectProperty
或 StringProperty
。在下面的代码中,我使用了 StringProperty
。
重要的是,您需要在您的应用 class 中使用 StringProperty
并在 kv 文件中使用它。
对于你计算的mode
,我添加了一个属性,所以你可以在你的计算方法中使用它。
mode
也用于 kv 文件中,因此它显示当前模式。
switcher
字典是 Python 执行 switch/case 语句的方法。
示例代码
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import StringProperty
kv = """
Screen:
side: side
GridLayout:
rows: 1
cols:2
spacing:0
GridLayout:
rows: 5
cols:1
Button:
text: "Cube"
# on_press: app.mode = self.text
on_press: app.setMode(self)
Button:
text: "Cuboid"
on_press: app.setMode(self)
Button:
text: "Cylinder"
on_press: app.setMode(self)
Button:
text: "Cone"
on_press: app.setMode(self)
Button:
text: "Sphere"
on_press: app.setMode(self)
FloatLayout:
Label:
text: "The Volume and surface area of a {}:".format(app.mode)
pos_hint: {"x":0.1, "y":0.8}
text_size: self.size
Label:
text:"Side:"
pos_hint: {"x":0.1, "y":0.7}
text_size: self.size
Label:
text:"Volume:"
pos_hint: {"x":0.1, "y":0.65}
text_size: self.size
Label:
text:"Surface Area:"
pos_hint: {"x":0.1, "y":0.6}
text_size: self.size
TextInput:
size_hint: (.4, None)
height: 26
multiline: False
pos_hint: {"x":0.24, "y":0.7}
id: side
text: app.sideText
on_text_validate: app.on_side_change(self)
Label:
text: app.volume
pos_hint: {"x":0.27, "y":0.65}
text_size: self.size
Label:
text: app.area
pos_hint: {"x":0.355, "y":0.6}
text_size: self.size
"""
class MyApp(App):
sideText = StringProperty("")
area = StringProperty("0 cm²")
volume = StringProperty("0 cm³")
mode = StringProperty("Cube")
def build(self):
return Builder.load_string(kv)
def setMode(self, btn):
self.mode = btn.text
def on_side_change(self, instance):
print(instance.text)
result = 0
try:
value = float(instance.text)
except:
# failed to convert
return
def cubeCalc(val):
return {
"volume": val * val * val,
"area": val * val
}
switcher = {
"Cube": cubeCalc
}
method = switcher.get(self.mode, "Unknown mode")
if method is not "Unknown mode":
result = method(value) # result is a dictionary with volume & area
#print(result)
print(self.volume)
self.volume = "{:.2f} cm³".format(result["volume"])
self.area = "{:.2f} cm²".format(result["area"])
if __name__ == "__main__":
MyApp().run()