Home > Net >  Accessing TextInput data in kivy without using ids
Accessing TextInput data in kivy without using ids

Time:04-18

here i've made a grid full of inputboxes using for-loop and added them to a dictionary to access later since i couldn't set id's in the python file. Now i'm trying to make a function that will make basic calculations based on the inputbox's data but i do not know how i can pass particular inputboxes in that function without using id's. Also the on_text function isn't working as i expected. I'm sure i'm missing something big here. Any guidance is appreciated.

from kivy.uix.textinput import TextInput
from kivy.uix.label import Label
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.stacklayout import StackLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.button import Button
from kivy.lang import Builder
from kivy.metrics import dp
from kivy.properties import StringProperty

Builder.load_file("gridtable.kv")

class MyBox(BoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        pass
class MyGrid(GridLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.cols=6
        self.textinputs = {}
        for i in range(48):
            key = i 1
            self.textinputs[key] = TextInput(multiline=False,font_size=dp(30),on_text=self.calc(key))
            self.add_widget(self.textinputs[key])
        
    def calc(self,key):
        print(self.textinputs[key])

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

if __name__ == "__main__":
    MyApp().run()        
<MyBox>:
    mygrid:my_grid
    orientation: "vertical"
    MyGrid:
        id: my_grid
        size_hint: 1,0.8
    BoxLayout:
        orientation: "horizontal"
        size_hint: 1,0.2
        BoxLayout:
            orientation: "vertical"
            Button: 
                text: "Expense Total:"
            Button: 
                text: "Revenue Total:"    
        Button:
            text: "Profit:"
            font_size: 40          
Traceback (most recent call last):
   File "c:\Users\jaika\OneDrive\Desktop\python\lil_curry_project\gridtable.py", line 38, in <module>
     MyApp().run()        

     print(self.textinputs[key])
 KeyError: 1
#better version of MyGrid()
class MyGrid(GridLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.cols=4
        self.textinputs = [0]
        self.expense = 0
        self.revenue = 0
        self.profit = 0
        for i in range(16):
            t = TextInput(multiline=False,text=str(i 1))
            t.bind(on_text_validate=self.calc_profit)
            self.textinputs.append(t)
            self.add_widget(t)
        
    def calc_profit(self,instance):
        index = self.textinputs.index(instance)
        if index == 1 or index == 2 or index == 5 or index == 6 or index == 9 or index == 10 or index == 13 or index == 14:
            self.expense  = int(instance.text)
        else:
            self.revenue  = int(instance.text)
        self.profit = self.revenue - self.expense
        print(self.profit)   


CodePudding user response:

You can use bind to trigger a method call, or use events available in the TextInput (like on_text_validate). Here is a modified MyGrid class that uses both:

class MyGrid(GridLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.cols = 6
        self.textinputs = {}
        for i in range(48):
            key = i   1
            self.textinputs[key] = TextInput(multiline=False, font_size=dp(30), on_text_validate=self.abba)
            self.textinputs[key].bind(text=partial(self.calc, key))
            print('in init, key =', key)
            self.add_widget(self.textinputs[key])

    def abba(self, ti_instance):
        print('abba, textinput instance =', ti_instance, ', text =', ti_instance.text)

    def calc(self, key, ti_instance, text):
        print('calc:')
        print('key =', key, ', text =', text, ', textinput instance =', ti_instance)

Note that the bind to text gets triggered with every change to the text in a TextInput. The on_text_validate will only be triggered when the user hits Enter.

  • Related