Search code examples
kivykivy-language

Add function to button in kivy file


I am trying to bind my calculations function to the submit button. I am new to Kivy and trying to get in some practice. Any tips or tricks for learning are greatly appreciated. Here is my code:

Python File:

import kivy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty

class MyGrid(Widget):
    pass
        

class MyApp(App):
    def build(self):
        return MyGrid()
    

    def calculations(self):
        org_amount = float(self.ids.orgamount.text)
        org_tip = int(self.ids.orgtip.text)
        org_split = int(self.ids.split1.text)

        tip1 = org_tip/100
        tip = round(tip1 * org_amount, 2)
        total = round(tip + org_amount, 2)
        if org_split == 0:
            split = org_split
        else:
            split = round(total/org_split,2)
   


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

KIVY FILE:

<MyGrid>:
title: 'tipBot       v1.0'
auto_dismiss: False

GridLayout:
    cols:2
    size: root.width * 0.8, root.height * 0.8
    

    row_default_height: 30
    row_force_default: True
    center: root.width/2, root.height/2

    Label:
        text: "Enter orginal bill amount: "
    TextInput:
        id: orgamount
        hint_text: 'Enter number w/ 2 decimal places'
        hint_text_color: 'blue'
        multiline:False

    Label:
        text: "How much tip will you leave: "
    TextInput:
        id: orgtip
        hint_text: 'Enter whole number'
        hint_text_color: 'blue'
        multiline:False

    Label:
        text: "How many patrons will split the bill: "
    TextInput:
        id: split1
        multiline: False

    Label:
        text: "Orignal Bill Amount: "
    TextInput:
        id: amount
        multiline: False

    Label:
        text: "Amount of tip: "
    TextInput:
        id: tip
        multiline: False

    Label:
        text: "Total with tip: "
    TextInput:
        id: withtip
        multiline: False

    Label:
        text:"Amount for each patron split: "
    TextInput:
        id:patronsplit
        multiline: False

    Button:
        id: Clear
        text: "Clear"
        size_hint_x: 0
        on_release:
            orgamount.text = ''
            orgtip.text = ''
            split1.text = ''
            amount.text = ''
            tip.text = ''
            withtip.text = ''
            patronsplit.text =''
            
    Button:
        id: Submit
        text: "Submit"
        size_hint_x:0.5
        on_press: root.calculations()
       
            enter code here

Solution

  • The problem is that in your kv, the line:

    on_press: root.calculations()
    

    is trying to call the calculations() method of the root object of the kv rule, which is MyGrid. The fix is to just move the calculations() method into MyGrid:

    class MyGrid(Widget):
        def calculations(self):
            org_amount = float(self.ids.orgamount.text)
            org_tip = int(self.ids.orgtip.text)
            org_split = int(self.ids.split1.text)
    
            tip1 = org_tip / 100
            tip = round(tip1 * org_amount, 2)
            total = round(tip + org_amount, 2)
            if org_split == 0:
                split = org_split
            else:
                split = round(total / org_split, 2)
    
    
    class MyApp(App):
        def build(self):
            return MyGrid()