簡體   English   中英

如何從添加小部件()獲取添加到屏幕的 kivy 變量

[英]How to get a kivy variable added to Screen from add widget()

因此,我試圖將一個變量添加到屏幕中,而我要添加的小部件中的 id 來自,例如,如果我有這個:

from kivy.app import App
from kivy.lang import Builder
from kivy.properties import StringProperty

kv = """
Screen:
    cal:cal
    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
            FloatLayout:
                id:cal
                Label:
                    text:"Side:"
                    pos_hint: {"x":1.1, "y":0.7}
                    text_size: self.size
                Label:
                    text:"Volume:"                
                    pos_hint: {"x":1.1, "y":0.65}
                    text_size: self.size
                Label:
                    text:"Surface Area:"                
                    pos_hint: {"x":1.1, "y":0.6}
                    text_size: self.size
                TextInput:
                    size_hint: (.4, None)
                    height: 26
                    multiline: False
                    pos_hint: {"x":1.24, "y":0.7}
                    id: side
                    text: app.sideText
                    on_text_validate: app.Cube_on_side_change(self)
                Label:                
                    text: app.volume
                    pos_hint: {"x":1.27, "y":0.65}
                    text_size: self.size
                Label:
                    text: app.surface_area
                    pos_hint: {"x":1.355, "y":0.6}
                    text_size: self.size
"""
cube = """
FloatLayout:
    Label:
        text:"Side:"
        pos_hint: {"x":1.1, "y":0.7}
        text_size: self.size
    Label:
        text:"Volume:"                
        pos_hint: {"x":1.1, "y":0.65}
        text_size: self.size
    Label:
        text:"Surface Area:"                
        pos_hint: {"x":1.1, "y":0.6}
        text_size: self.size
    TextInput:
        size_hint: (.4, None)
        height: 26
        multiline: False
        pos_hint: {"x":1.24, "y":0.7}
        id: side
        text: app.sideText
        on_text_validate: app.Cube_on_side_change(self)
    Label:                
        text: app.volume
        pos_hint: {"x":1.27, "y":0.65}
        text_size: self.size
    Label:
        text: app.surface_area
        pos_hint: {"x":1.355, "y":0.6}
        text_size: self.size"""

cuboid = """
FloatLayout:
    id:main
    Label:
        text:"Length:"
        pos_hint: {"x":1.1, "y":0.7}
        text_size: self.size
    Label:
        text:"Breadth:"                
        pos_hint: {"x":1.1, "y":0.65}
        text_size: self.size
    Label:
        text:"Height:"                
        pos_hint: {"x":1.1, "y":0.6}
        text_size: self.size
    TextInput:
        size_hint: (.4, None)
        height: 26
        multiline: False
        pos_hint: {"x":1.24, "y":0.7}
        id: length
        text: app.sideText
        on_text_validate: app.Cuboid_on_side_change(self)
    TextInput:
        size_hint: (.4, None)
        height: 26
        multiline: False
        pos_hint: {"x":1.24, "y":0.65}
        id: breadth
        text: app.sideText
        on_text_validate: app.Cube_on_side_change(self)
    TextInput:
        size_hint: (.4, None)
        height: 26
        multiline: False
        pos_hint: {"x":1.24, "y":0.6}
        id: height
        text: app.sideText
        on_text_validate: app.Cuboid_on_side_change()
    Label:                
        text: "Volume:"
        pos_hint: {"x":1.1, "y":0.55}
        text_size: self.size
    Label:
        text: "Surface Area:"
        pos_hint: {"x":1.1, "y":0.5}
        text_size: self.size
    Label:                
        text: app.volume
        pos_hint: {"x":1.27, "y":0.55}
        text_size: self.size
    Label:
        text: app.surface_area
        pos_hint: {"x":1.355, "y":0.5}
        text_size: self.size"""
cone = """
FloatLayout:
    Label:
        text:"Radius:"
        pos_hint: {"x":1.1, "y":0.7}
        text_size: self.size
    Label:
        text:"Height:"                
        pos_hint: {"x":1.1, "y":0.65}
        text_size: self.size
    TextInput:
        size_hint: (.4, None)
        height: 26
        multiline: False
        pos_hint: {"x":1.24, "y":0.7}
        id: Radius
        text: app.sideText
        on_text_validate: app.Cuboid_on_side_change(self)
    TextInput:
        size_hint: (.4, None)
        height: 26
        multiline: False
        pos_hint: {"x":1.24, "y":0.65}
        id: height
        text: app.sideText
        on_text_validate: app.Cube_on_side_change(self)
    Label:                
        text: "Volume:"
        pos_hint: {"x":1.1, "y":0.6}
        text_size: self.size
    Label:
        text: "Surface Area:"
        pos_hint: {"x":1.1, "y":0.55}
        text_size: self.size
    Label:                
        text: app.volume
        pos_hint: {"x":1.27, "y":0.6}
        text_size: self.size
    Label:
        text: app.surface_area
        pos_hint: {"x":1.355, "y":0.55}
        text_size: self.size
"""
screens = {
    "Cube": cube,
    "Cuboid": cuboid,
    "Cone": cone
}
class MyApp(App):
    sideText = StringProperty("")
    surface_area = StringProperty("0 cm²")
    volume = StringProperty("0 cm³")
    mode = StringProperty("Cube")

    def build(self):
        self.screen = Builder.load_string(kv)

        return self.screen

    def setMode(self, btn):
        self.volume = "0 cm³"
        self.surface_area = "0 cm³"
        self.mode = btn.text
        self.screen.cal.clear_widgets()
        self.screen.cal.add_widget(Builder.load_string(screens[self.mode]))

    def Cube_on_side_change(self, instance):

        try:
            value = float(instance.text)
            num = True
        except ValueError:
            # failed to convert
            num = False
            print("Numbers only idiot.")

        def cubeCalc(val):
            return {
                "volume": val * val * val,
                "surface_area": (val * val) * 6
            }

        if num:
            result = cubeCalc(value)
            self.volume = "{:.2f} cm³".format(result["volume"])
            self.surface_area = "{:.2f} cm²".format(result["surface_area"])

    def Cuboid_on_side_change(self):
        height = self.screen.cal.ids.main.height.text
        try:
            value = float(height)
            num = True
        except ValueError:
            # failed to convert
            num = False
            print("Numbers only idiot.")

        def cubeCalc(val):
            return {
                "volume": val * val * val,
                "surface_area": (val * val) * 6
            }

        if num:
            result = cubeCalc(value)
            self.volume = "{:.2f} cm³".format(result["volume"])
            self.surface_area = "{:.2f} cm²".format(result["surface_area"])


if __name__ == "__main__":
    MyApp().run() 

on_text_validate TextInput with id:height在字符串長方體中,我想從文本輸入中獲取文本,例如: self.screen.main.height.text ,但是,要做到這一點,我必須添加main:mainheight:heightScreen 我該怎么做?

我建議重構你的代碼。 與其重新發明ScreenManager的功能,不如使用ScreenManager 在您的kv字符串中,將FloatLayout替換為:

ScreenManager:
    CubeScreen:
    CuboidScreen:
    ConeScreen:

並使用您的附加kv字符串(如cube )作為kv字符串中附加規則的基礎。 就像是:

<CubeScreen>:
    Label:
        text: "The Volume and surface area of a Cube:"
        pos_hint: {"x":0.1, "y":0.8}
        text_size: self.size
        FloatLayout:
            Label:
                text:"Side:"
                pos_hint: {"x":0.1, "y":0.7}
                text_size: self.size
         .
         .
         .

並在您的py中定義每個Screen class ,例如:

class CubeScreen(Screen):
    def get_cube_area(self):
        .
        .
        .

在每個新類(如CubeScreen )中,您可以定義用於計算面積、體積等的方法,並且可以使用它們的ids輕松訪問TextInputs 並且您在每個Screen中的on_text_validate可以只從該Screen調用適當的方法(例如on_text_validate: root.get_cube_area() )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM