在两个 kivy 屏幕中添加两个值并得到结果

Posted

技术标签:

【中文标题】在两个 kivy 屏幕中添加两个值并得到结果【英文标题】:adding two Values in two kivy screens and getting the result 【发布时间】:2020-05-17 08:34:28 【问题描述】:

我正在尝试构建一个可以计算两个值之和的应用程序。我有一个名为 Therdwindow 的屏幕,其中包含三个文本输入小部件。

from kivy.app import App 
from kivy.app import App 
from kivy.uix.label import Label
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.scatter import Scatter
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.textinput import TextInput
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen`
class MainWindow(Screen):
    pass
class SecondWindow(Screen):
    pass
class Therdwindow(Screen):
    pass
class Fourwindow(Screen):
    pass
class FunfthWindow(Screen):
    def calculate3(self,bibi,mimi):
        kiki = str(float(bibi) + float(mimi))
        if kiki:
            try :
                self.result_1.text = str(eval(kiki)) 
            except Exception: 
                self.result_1.text = 'Error'

class Sixwindow(Screen):
    pass
class WindowManager(ScreenManager):
    psss
kv = Builder.load_file("layout.kv")
class MyMainApp(App):
    def build(self):
        return kv
if __name__ == "__main__":
    MyMainApp().run()

一个人应该输入密码“gin”,然后单击“NEXT”按钮进入名为 SecondWindow 的下一个屏幕,然后单击“NEXT”按钮进入名为 TherdWindow 的下一个屏幕,

然后在框中输入第一个值,然后单击“下一步”按钮转到名为fourWindow 的下一个屏幕, 比输入第二个值并单击“下一步”按钮转到名为 funfthWindow 的下一个屏幕。

如果他点击一个按钮结果应该有“结果”。在此屏幕中,有一个标签应该打印该人指定的总和的体积。

layout.kv

<CustButton@Button>: 
     font_size: 40
WindowManager:
    MainWindow:
    SecondWindow:
    Therdwindow:
    Fourwindow:
    FunfthWindow:
    Sixwindow:

<MainWindow>:
     name: "main"

    <MainWindow>:
        name: "main"
        GridLayout:
            cols:1

            GridLayout:
                cols: 2
                orientation: 'vertical'

                Label:
                    text: "Password: "
                    font_size: "40sp"
                    background_color: (1,1,0,1)
                    font_name: 'RobotoMono-Regular.ttf'

                TextInput:
                    id: passw
                    multiline: False
                    font_size: "40sp"

            CustButton:
                text: "Submit"
                background_color: (0.8,0.8,0,1)
                on_press:
                    app.root.current = "second" if passw.text == "gin" else "six"
                    root.manager.transition.duration = 1 
                    root.manager.transition.direction = "left"


<SecondWindow>:
     name: "second"

     GridLayout:

         cols: 1
         spacing: 10
         CustButton:
             text: "Go Back"
             on_press:
                 app.root.current = "main"
                 root.manager.transition.direction = "right"

         CustButton:
             text: "next"
             on_press:
                 app.root.current = "therd"
                 root.manager.transition.direction = "left"


<Therdwindow>:
     id:lulu
     name: "therd"
     nani:feras1
     rows: 20
     padding: 0
     spacing: 2



     GridLayout:
         spacing: 10
         cols:2
         Label:
             text: "Enter The First Value :  "
             font_size: "30sp"


         TextInput: 
             id:first_Value
             font_size: 40
             multiline: True



         CustButton: 
             text: "go back"
             on_press:
                 app.root.current = "second"
                 root.manager.transition.direction = "right"

         CustButton: 
             text: "Next"
             on_press:
                 app.root.current = "four"
                 root.manager.transition.direction = "left"


<Fourwindow>:
     id:lala
     name: "four"
     nani21:feras2
     rows: 20
     padding: 0
     spacing: 2



     GridLayout:
         spacing: 10
         cols:2
         Label:
             text: "Enter The second Value : "
             font_size: "30sp"



         TextInput: 
             id: second_Value
             font_size: 40
             multiline: True



         CustButton: 
             text: "go back"
             on_press:
                 app.root.current = "therd"
                 root.manager.transition.direction = "right"

         CustButton: 
             text: "NEXT"
             on_press:
                 app.root.current = "funfth"
                 root.manager.transition.direction = "left"


<FunfthWindow>: 
     id:CalcmGridLayout
     name: "funfth"            
     result_1:label_id
     rows: 20
     padding: 0
     spacing: 2



     GridLayout:
         spacing: 10
         cols:2

         CustButton: 
             text: "Result :  "
             font_size: "30sp"
             on_press:CalcmGridLayout.calculate3(first_Value.text,second_Value.text)

         Label: 
             id: label_id
             font_size: 40
             multiline: True    

         CustButton: 
             text: "go back"
             on_press:
                 app.root.current = "four"
                 root.manager.transition.direction = "right"

         CustButton: 
             text: "NEXT"
             on_press:
                 app.root.current = "main"
                 root.manager.transition.direction = "left"


<Sixwindow>:
     name: "six"            
     GridLayout:
         cols: 1
         spacing: 10
         Label:
             text: 'das Password ist falsch'
             font_size: "40sp"

         CustButton:
             text: "nochmal"
             on_press:
                 app.root.current = "main"
                 root.manager.transition.direction = "right"

当我点击“结果”时,我收到此错误NameError : first_Value is not defined

请帮忙。我非常感谢任何建议。

【问题讨论】:

【参考方案1】:

嗯,有很多方法可以做到这一点,为简单起见,我将在 MyMainApp 类中执行所有操作:

 from kivy.properties import ObjectProperty
 from Kivy.clock import Clock
...
class Therdwindow(Screen):

    first_Value = ObjectProperty(None)

    def getvalue(self):
        return self.first_Value

class Fourwindow(Screen):

    second_Value = ObjectProperty(None)

    def getvalue(self):
        return self.second_Value

class FunfthWindow(Screen):

    label_id = ObjectProperty(None)

    def getlabel(self):
        return self.label_id

class WindowManager(ScreenManager):
    pass


class MyMainApp(App):
    def build(self):
        with open('layout.kv', encoding='utf-8', errors='ignore') as f:
            Builder.load_string(f.read())
        # creating objects of screens
        self.mainwindow = MainWindow()
        self.secondwindow = SecondWindow()
        self.therdwindow = Therdwindow()
        self.fourwindow = Fourwindow()
        self.funfthwindow = FunthWindow()

        # creating object of screen manager
        self.sm = WindowManager()

        # getting all object properties
        self.first_Value = self.therdwindow.getvalue()
        self.second_Value = self.fourwindow.getvalue()
        self.label_id = self.funfthwindow.getlabel()

        # connecting object properties to widgets from kv file
        # sometimes we need to delay that, because the app can't load so quickly, so let's make a method for it
        Clock.schedule_once(self.getids)

        # adding screens to screen manager
        self.sm.add_widget(self.mainwindow)
        self.sm.add_widget(self.secondwindow)
        self.sm.add_widget(self.therdwindow)
        self.sm.add_widget(self.fourwindow)
        self.sm.add_widget(self.funfthwindow)
        # in case you want screen manager be able to work you should return it
        return self.sm

    def getids(self):
        self.first_Value = self.therdwindow.ids.first_Value
        self.second_Value = self.fourwindow.ids.second_Value
        self.label_id = self.funfthwindow.ids.label_id

    # method that does what you want
    def count(self):
        self.label_id.text = str(int(self.first_Value.text) + int(self.second_Value.text))

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

你需要编辑你的 kv 文件,改变所有这些

on_press:
    app.root.current = "second"

到那个:

on_press:
    app.sm.current = "second"

然后改变这个:

CustButton: 
             text: "Result :  "
             font_size: "30sp"
             on_press:CalcmGridLayout.calculate3(first_Value.text,second_Value.text)

到这里:

CustButton: 
             text: "Result :  "
             font_size: "30sp"
             on_press: app.count

您还需要在类中添加这些行:

<Therdwindow>:
    ...
    first_Value: first_Value.__self__

<Fourwindow>:
    ...
    second_Value: second_Value.__self__

<FunfthWindow>:
    ...
    label_id: label_id.__self__

然后删除:

WindowManager:
    MainWindow:
    SecondWindow:
    Therdwindow:
    Fourwindow:
    FunfthWindow:
    Sixwindow:

【讨论】:

【参考方案2】:

您正在尝试在另一个规则中使用来自一个规则的ids,但ids 仅适用于当前规则。因此,kv 中的这一行将不起作用:

on_press:CalcmGridLayout.calculate3(first_Value.text,second_Value.text)

解决此问题的一种方法是访问ids,首先获取定义idScreen,这在kv 之外更容易完成。因此,我建议将上述行替换为:

on_press:root.calculate3()

然后稍微重写您的 calculate3() 方法以访问其他值:

class FunfthWindow(Screen):
    def calculate3(self):
        bibi = App.get_running_app().root.get_screen('therd').ids.first_Value.text
        mimi = App.get_running_app().root.get_screen('four').ids.second_Value.text
        kiki = str(float(bibi) + float(mimi))
        if kiki:
            try :
                self.ids.label_id.text = str(eval(kiki))
            except Exception:
                self.ids.label_id.text = 'Error'

【讨论】:

嗨约翰,谢谢你的回答我现在有这个问题((((((self.ids.label_id.text = str(eval(kiki))文件“kivy\properties.pyx”,行863,在 kivy.properties.ObservableDict.__getattr__ AttributeError: 'super' 对象没有属性 'getattr' )))))) 我如何添加属性 'getattr' ?你能帮我解决这个问题吗 您不能添加getattr 属性。该错误向我表明FunfthWindow 不包含ids 字典中的label_id。如果在填写 ids 之前(即在显示 FunfthWindow 之前)调用了 calculate3() 方法,或者如果在 layout.kv 文件中未正确定义 label_id,则可能会发生这种情况。我无法确定问题出在哪里,因为我无法产生该错误。 你好 John,谢谢,它有效 :) 现在我有一个小问题:(((如果我想在 Therd 窗口中创建一个动态数组,我添加三个或更多或更少.. 示例:用户可以进入First_Value_in_Therd_Window,然后点击“添加一行”按钮进入The Second_Value_in_Therd_Window,然后他可以点击“添加一行”按钮进入下一个值,然后点击“下一步”进入第四个添加值的窗口:First_Value_in_fourth_window .. 第二个和第三个以相同的方式。比在下一个窗口中他将第一个添加到第一个和第二个到第二个))我怎样才能制作这个动态数组? 你应该为此发布一个新问题。

以上是关于在两个 kivy 屏幕中添加两个值并得到结果的主要内容,如果未能解决你的问题,请参考以下文章

更改两个不同 kivy 屏幕的大小

Python Kivy - 在另一个屏幕上显示动态结果

无法用kivy显示图像

Kivy - 通过引用根属性动态添加按钮

从回收视图中将回收视图项目添加到另一个屏幕 - kivy

仅计算两个不同列中的空值并显示在一个选择语句中