1

I'm trying to build an app that can calculate the sum of two values. I have a screen called Therdwindow that has three text input widgets.

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()

A person is supposed to enter the Password 'gin' than click on a button 'NEXT' to go to the next screen named SecondWindow , then click on a button 'NEXT' to go to the next screen named TherdWindow ,

Then enter a First Value in the Box then click on a button 'NEXT' to go to the next screen named fourWindow , than enter the second Value and click on a button 'NEXT' to go to the next screen named funfthWindow .

there should have the 'Result' if he click on a button result. In this screen there is a Label that should print the volume of the sum that the person specified.

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"

When I click of 'Result' I get this Error NameError : first_Value is not defined

please help. I would really appreciate any advice.

Cleptus
  • 3,446
  • 4
  • 28
  • 34
jan
  • 33
  • 8

2 Answers2

0

Well, there's a lot of ways to do that, for the simplicity I'll do all operations in the MyMainApp class:

 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()

And you need to edit your kv file, change all that

on_press:
    app.root.current = "second"

to that:

on_press:
    app.sm.current = "second"

And change this:

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

to this:

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

Also you need to add that lines in classes:

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

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

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

And delete this:

WindowManager:
    MainWindow:
    SecondWindow:
    Therdwindow:
    Fourwindow:
    FunfthWindow:
    Sixwindow:
Lothric
  • 1,283
  • 2
  • 6
  • 11
0

You are trying to use ids from one rule inside another rule, but ids are only available for the current rule. So, this line in your kv will not work:

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

A way to fix this, is to access the ids by first getting the Screen where that id is defined, and that is more easily done outside of kv. So, I would recommend replacing the above line with:

on_press:root.calculate3()

And then rewrite your calculate3() method slightly to access the other values:

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'
John Anderson
  • 35,991
  • 4
  • 13
  • 36
  • hi john , thanks for your Answer ihave this proplem now (((((( self.ids.label_id.text = str(eval(kiki)) File "kivy\properties.pyx", line 863, in kivy.properties.ObservableDict.__getattr__ AttributeError: 'super' object has no attribute '__getattr__' )))))) how can i add attribute '__getattr__' ? can you maybe help me in this issue – jan Feb 06 '20 at 09:32
  • You can't add the `getattr` attribute. The error suggests to me that the `FunfthWindow` does not contain the `label_id` in the `ids` dictionary. That can happen if the `calculate3()` method is called before the `ids` are filled in (i.e., before the `FunfthWindow` is displayed), or if the `label_id` is not defined correctly in the `layout.kv` file. I can't be sure what the problem is because I cannot produce that error. – John Anderson Feb 06 '20 at 14:31
  • Hello John, thanks , it works :) Now I have a little question: (((If I want to create a dynamic array in the Therd window, I add three or more or less.. Example : the User can enter The First_Value_in_Therd _Window, than can click "Add a line" Buttun to enter The Second_Value_in_Therd _Window, Than he can click "Add a line" Buttun to enter The next Value,than he clicks "next" to go to fourth Window to add the Values :First_Value_in_fourth_window .. second and therd in the same way.than in the next Window he adds First to First and second to second)) How can i make this dynamic array ? – jan Feb 06 '20 at 19:41
  • You should post a new question for that. – John Anderson Feb 06 '20 at 22:02