2017-10-14 7 views
0

J'ai des programmes écrits dans des versions précédentes de Kivy qui utilisent ListViews. En utilisant ListViews, il était assez facile d'obtenir le nœud sélectionné via l'adaptateur. Cependant, il est beaucoup moins clair comment le faire avec un RecycleView. Maintenant, c'est le cas rv.layout_manager.selected_nodes peut être utilisé pour obtenir la valeur sélectionnée, mais il y a aussi des moments où je suis intéressé par le nœud réel. En outre, l'extrait suivant peut être utilisé pour générer les noeuds, mais apparemment, ils ne sont pas les noeuds réels dans RecycleView.Récupère le nœud sélectionné dans 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 

Je serais intéressé de trouver un moyen d'obtenir le nœud sélectionné à partir de RecycleView.

code complet:

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() 

Répondre

1

s'il vous plaît nous montrer votre code. dans le rv.data vous pouvez ajouter un paramètre « sélectionné » = 0 lorsque le noeud n'est pas sélectionné et 1 lorsqu'il est ceci est un exemple:

class TestRecycleView(RecycleView): 

    def __init__(self, **kwargs): 
     super(TestRecycleView, self).__init__(**kwargs) 
     self.data = [{'name': 'test', 'ind':0,'selected': 0}] 

class TestBox(RecycleDataBehaviour, BoxLayout): 
    def action(self, boss): 
     if boss.data[self.ind]['selected'] == 0: 
     boss.data[self.ind]['selected'] = 1 
     else: 
     boss.data[self.ind]['selected'] = 0 

kv:

<TestRecycleView>: 
    viewclass: 'TestBox' 
    RecycleBoxLayout: 
     default_size: None, 440 
     default_size_hint: 1, None 
     size_hint_y: None 
     height: self.minimum_height 
     orientation: 'vertical' 
<TestBox>: 
    Button: 
     on_press: root.action(root.parent.parent) 

si i bien comprendre que vous voulez imprimer la valeur selectedLabel:

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 self.rv.data[val[0]]['text'] 

proof(image link)

+0

Mon erreur. J'avais listé le mauvais fichier d'exemple. Le code est édité dedans. Mon but est d'obtenir les noeuds choisis dehors du manager de recycleView.layout. –

+0

J'ai mis à jour ma réponse, l'espoir est ce que vous vouliez @PistolPete –

+0

il s'est avéré que je cherchais au mauvais endroit. Mon objectif était d'obtenir les widgets sélectionnés, et je cherchais dans '' rv.layout_manager''. Il s'avère que j'aurais dû regarder dans '' rv.view_adapter.views''. Mais merci pour l'aide. –