如何获取、使用和更改 .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_fileBuilder.load_string 放入您的 build 方法中。

处理变化,例如如果用户在侧面输入中点击回车,使用 on_text_validate: app.on_side_change(self) 或放置一个按钮来触发计算并使用 on_press 方法。

您的 class MyApp 中的 on_side_change 方法将处理更改。一旦用户点击回车,它就会被调用。有关基本计算,请参阅下面的示例代码。

对于 labels/inputs 中的 getting/setting 值,您可以使用 kivy.properties 中的 ObjectPropertyStringProperty。在下面的代码中,我使用了 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()