ListViews를 사용하는 Kivy의 이전 버전으로 작성된 프로그램이 있습니다. ListView를 사용하면 어댑터를 통해 선택한 노드를 얻는 것이 매우 쉬웠습니다. 그러나 RecycleView를 사용하여이를 수행하는 방법이 훨씬 명확하지 않습니다. 이제, rv.layout_manager.selected_nodes
을 사용하여 선택한 값을 얻을 수 있지만 실제 노드에 관심이있는 시간도 있습니다. 또한 다음 스 니펫을 사용하여 노드를 생성 할 수는 있지만 RecycleView의 실제 노드는 아닙니다.Kivy Recycleview에서 선택된 노드 가져 오기
opts = rv.layout_manager.view_opts
for i in range(len(rv.data)):
s = rv.view_adapter.get_view(i, rv.data[i], opts[i]['viewclass'])
print s.text, s.selected
저는 RecycleView에서 선택한 노드를 가져 오는 방법을 찾는 데 관심이 있습니다.
전체 코드 :
import random
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.label import Label
from kivy.properties import BooleanProperty
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
#Aside: the code in the string would need to be indented back one tab, but it's like this for SO formatting
Builder.load_string('''
<SelectableLabel>:
# Draw a background to indicate selection
canvas.before:
Color:
rgba: (.0, 0.9, .1, .3) if self.selected else (0, 0, 0, 1)
Rectangle:
pos: self.pos
size: self.size
<RV>:
viewclass: 'SelectableLabel'
SelectableRecycleBoxLayout:
key_selection: "True"
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
multiselect: False
touch_multiselect: True
touch_deselect_last: True
''')
class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior,
RecycleBoxLayout):
''' Adds selection and focus behaviour to the view. '''
class SelectableLabel(RecycleDataViewBehavior, Label):
''' Add selection support to the Label '''
index = None
selected = BooleanProperty(False)
selectable = BooleanProperty(True)
def refresh_view_attrs(self, rv, index, data):
''' Catch and handle the view changes '''
self.index = index
return super(SelectableLabel, self).refresh_view_attrs(
rv, index, data)
def on_touch_down(self, touch):
''' Add selection on touch down '''
if super(SelectableLabel, self).on_touch_down(touch):
return True
if self.collide_point(*touch.pos) and self.selectable:
return self.parent.select_with_touch(self.index, touch)
def apply_selection(self, rv, index, is_selected):
''' Respond to the selection of items in the view. '''
self.selected = is_selected
class RV(RecycleView):
def __init__(self, **kwargs):
super(RV, self).__init__(**kwargs)
self.data = [{'text': str(random.random())} for x in range(20)]
class TestApp(App):
def build(self):
self.rv = RV()
self.rv.layout_manager.bind(selected_nodes=self.selectionChange)
return self.rv
def selectionChange(self, inst, val):
print inst, val
if __name__ == '__main__':
b = TestApp()
b.run()
내 실수. 잘못된 예제 파일을 나열했습니다. 코드는에서 편집됩니다. 내 목표는 recycleView.layout_manager 밖으로 선택한 노드를 얻는 것입니다. –
나는 나의 대답을 갱신했다, 희망은 당신이 원하는 것이다. @PistolPete –
그것은 내가 틀린 장소에서 찾고 있다고 밝혀졌다. 내 목표는 선택된 위젯을 얻는 것이었고''rv.layout_manager''를보고있었습니다. ''rv.view_adapter.views''를보고 있어야한다는 것이 밝혀졌습니다. 그러나 도움에 감사드립니다. –