在不使用 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)
请注意,bind
到 text
会随着 TextInput
中文本的每次更改而触发。 on_text_validate
只会在用户点击 Enter
时触发。
这里我使用 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)
请注意,bind
到 text
会随着 TextInput
中文本的每次更改而触发。 on_text_validate
只会在用户点击 Enter
时触发。