在不使用 id 的情况下访问 kivy 中的 TextInput 数据

Accessing TextInput data in kivy without using ids

这里我使用 for-loop 制作了一个充满输入框的网格,并将它们添加到字典中以便稍后访问,因为我无法在 python 文件中设置 id。现在我正在尝试创建一个函数,该函数将根据输入框的数据进行基本计算,但我不知道如何在不使用 id 的情况下在该函数中传递特定的输入框。 on_text 函数也没有像我预期的那样工作。我确定我在这里遗漏了一些重要的东西。任何指导表示赞赏。

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)   


您可以使用 bind 触发方法调用,或使用 TextInput 中可用的事件(如 on_text_validate)。这是一个修改后的 MyGrid class,它同时使用:

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)

请注意,bindtext 会随着 TextInput 中文本的每次更改而触发。 on_text_validate 只会在用户点击 Enter 时触发。