[英]Update kivy recycleview self.data from textinput change
我無法弄清楚如何從 UI 上的文本輸入更改中更新數據。 我一直在嘗試將我的代碼基於以下內容: 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()
這是在我更改值文本輸入框之后。 之前是指驗證分類和時間然后更改數據。 執行 validate() 后,textinput 文本恢復為原來的數字:
之前:{'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'}
之前:{'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'}
我在這里想念什么? 謝謝您的幫助!
我從 discord 上的 Kivy 論壇得到了答案。 關鍵是將索引傳遞給行小部件,以便他們可以更改行的數據。 我認為這應該適用於 recycleview object 中的任何復雜小部件。 希望這可以幫助某人。
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.