[英]Update kivy recycleview self.data from textinput change
I haven't been able to figure out how to do update the data from a change in the text input on the UI.我无法弄清楚如何从 UI 上的文本输入更改中更新数据。 I've been trying to base my code on the following: https://github.com/kivy/kivy/issues/5318
我一直在尝试将我的代码基于以下内容: https://github.com/kivy/kivy/issues/5318
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.recycleview import RecycleView
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.textinput import TextInput
import re
string_to_build_recycleview = '''
<rowTest@BoxLayout>:
#canvas:
# Rectangle:
# size: self.size
# pos: self.pos
name_text: 'Someone Else'
stroke_text: 'Butterfly'
classification_text: '3'
time_text: '9:99.99'
BoxLayout:
orientation: 'horizontal'
Label:
id: name
text: root.name_text
Label:
id: stroke
text: root.stroke_text
ClassificationTI:
id: classification
padding: (8, 1, 2, 1)
halign: 'center'
size: (20,20)
multiline: 'False'
input_filter: 'int'
text: root.classification_text
on_text: root.classification_text = self.text
TimeTI:
padding: (8, 1, 2, 1)
halign: 'center'
size: (20,20)
multiline: 'False'
text: root.time_text
#on_text: root.time_text = self.text
<RecycleViewTEST@RecycleView>:
id: myListToTest
scroll_type: ['bars', 'content']
#scroll_wheel_distance: dp(114)
bar_width: dp(10)
viewclass: 'rowTest'
RecycleBoxLayout:
default_size: None, dp(20)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
spacing: dp(2)
'''
class ClassificationTI(TextInput):
def insert_text(self,substr,from_undo=False):
if substr.isnumeric():
return super(ClassificationTI, self).insert_text(substr,from_undo=from_undo)
return super(ClassificationTI, self)
class TimeTI(TextInput):
def insert_text(self,substr,from_undo=False):
if substr.isnumeric() or substr == ":" or substr == ".":
return super(TimeTI, self).insert_text(substr,from_undo=from_undo)
return super(TimeTI, self)
class RecycleViewTEST(RecycleView):
def __init__(self, **kwargs):
super(RecycleViewTEST, self).__init__(**kwargs)
Builder.load_string(string_to_build_recycleview)
self.initial_populate()
def on_enter(self, *args):
self.get_real_data()
def initial_populate(self):
data = (('TheFirstOne', 'free', '9', '1:01.60'),('TheSecondOne', 'free', '9', '1:01.60'))
self.data = [{'name_text':n,'stroke_text':s,'classification_text':c,'time_text':t} for n,s,c,t in data]
print(self.data)
def validate_classification(self,classification):
if classification.isnumeric() and int(classification) > 14 and int(classification) < 1:
return "Not Valid"
return classification
def validate_time(self,time):
if re.match(r"([0-9]?[0-9]:)?([0-5][0-9])\.([0-9][0-9])", time) is None:
return "Not Valid"
return time
def do_stuff(self):
for i in range(len(self.data)):
print(self.data[i])
self.data[i]['classification_text'] = self.validate_classification(self.data[i]['classification_text'])
self.data[i]['time_text'] = self.validate_time(self.data[i]['time_text'])
print(self.data[i])
self.refresh_from_data()
string_to_build_the_form = '''
<TheForm>:
BoxLayout:
orientation: 'vertical'
BoxLayout:
orientation: 'horizontal'
Label:
size_hint: (None, None)
size: (200, 27)
text: '[u]Name[/u]'
markup: True
Label:
size_hint: (None, None)
size: (200, 27)
text: '[u]Stroke[/u]'
markup: True
Label:
size_hint: (None, None)
size: (190, 27)
text: '[u]Class[/u]'
markup: True
Label:
size_hint: (None, None)
size: (200, 27)
text: '[u]Time (mm:ss.hh)[/u]'
markup: True
BoxLayout:
size_hint: (1,None)
RecycleViewTEST:
id: myListToTest
BoxLayout:
orientation: 'horizontal'
Button:
size_hint: (None,None)
size: (150,50)
text: "Validate"
on_release: root.validate()
Button:
id: save_recalc
size_hint: (None,None)
size: (150,50)
text: "Save & Recalculate"
disabled: True
'''
class TheForm(BoxLayout):
def __init__(self, **kwargs):
super(TheForm, self).__init__(**kwargs)
Builder.load_string(string_to_build_the_form)
def validate(self, *args):
self.ids.myListToTest.do_stuff()
self.ids.save_recalc.disabled = False
class TheTEST(App):
def build(self):
sm = TheForm()
return sm
if __name__ == '__main__':
TheTEST().run()
This is after I change the values text input boxes.这是在我更改值文本输入框之后。 The before refers to validating the classification and time then changing the data.
之前是指验证分类和时间然后更改数据。 After executing validate(), the textinput text returns to the original numbers:
执行 validate() 后,textinput 文本恢复为原来的数字:
BEFORE: {'name_text': 'TheFirstOne', 'stroke_text': 'free', 'classification_text': '9', 'time_text': '1:01.60'}之前:{'name_text':'TheFirstOne','stroke_text':'free','classification_text':'9','time_text':'1:01.60'}
AFTER: {'name_text': 'TheFirstOne', 'stroke_text': 'free', 'classification_text': '9', 'time_text': '1:01.60'}之后:{'name_text':'TheFirstOne','stroke_text':'free','classification_text':'9','time_text':'1:01.60'}
BEFORE: {'name_text': 'TheSecondOne', 'stroke_text': 'free', 'classification_text': '9', 'time_text': '1:01.60'}之前:{'name_text':'TheSecondOne','stroke_text':'free','classification_text':'9','time_text':'1:01.60'}
AFTER: {'name_text': 'TheSecondOne', 'stroke_text': 'free', 'classification_text': '9', 'time_text': '1:01.60'}之后:{'name_text':'TheSecondOne','stroke_text':'free','classification_text':'9','time_text':'1:01.60'}
What am I missing here?我在这里想念什么? Thanks for the help!
谢谢您的帮助!
I got an answer from the Kivy forums on discord.我从 discord 上的 Kivy 论坛得到了答案。 The key is to pass a index to the row widget so they can change the data for their row.
关键是将索引传递给行小部件,以便他们可以更改行的数据。 I think this should work for any complex widget in a recycleview object.
我认为这应该适用于 recycleview object 中的任何复杂小部件。 Hope this helps someone.
希望这可以帮助某人。
from kivy.app import App
from kivy.properties import ObjectProperty, NumericProperty, ListProperty
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.textinput import TextInput
from kivy.lang.builder import Builder
KV = """
<RecycleItem>:
on_text: if root.owner != None: self.owner.data[self.index]['text'] = self.text
RecycleView:
data: app.data
viewclass: 'RecycleItem'
RecycleBoxLayout:
spacing: 10
default_size: None, dp(80)
default_size_hint: 1, None
orientation: 'vertical'
size_hint_y: None
height: self.minimum_height
"""
class RecycleItem(RecycleDataViewBehavior,TextInput):
owner = ObjectProperty()
index = NumericProperty(0)
def refresh_view_attrs(self, rv, index, data):
self.index = index
print("INDEXXXXXX: ",self.index)
return super(RecycleItem, self).refresh_view_attrs(rv, index, data)
class Test(App):
data = ListProperty()
def build(self):
self.data = [{"text": "Label "+str(x), 'owner': self} for x in range(20)]
return Builder.load_string(KV)
Test().run()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.