Kivy multiple choice with checkboxes

I am trying to create a view using Kivy that has a list of all options, all selected by default, and the user can deselect some of the entries (by clicking a checkbox or anywhere in the row).

Clicking on the row item label item works, but I noticed that clicking on that checkbox does not change the selection, which I cannot work out how to solve (I tried several different states, I left them commented out in the code example)

Here's a quick example showing what I've tried.

from kivy.app import App
from kivy.properties import StringProperty, ListProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.selectableview import SelectableView
from kivy.uix.togglebutton import ToggleButtonBehavior
from kivy.adapters.models import SelectableDataItem
from kivy.lang import Builder

Builder.load_string("""
#: import ListAdapter kivy.adapters.listadapter.ListAdapter
#: import Factory kivy.factory.Factory

<MyListItem>:
    height: 50

    on_state: root.is_selected = args[1] == "down"
    state: "down" if root.is_selected else "normal"

    BoxLayout:
        spacing: 10

        CheckBox:
            on_state: root.is_selected = args[1] == "down"
            state: "down" if root.is_selected else "normal"
            # on_state: root.state = args[1]
            # state: root.state

        Label:
            text: root.name

<Page>:
    orientation: "vertical"

    ListView:
        id: LV
        adapter: ListAdapter(data=root.data, cls=Factory.MyListItem, args_converter=root.args_converter, selection_mode="multiple", propagate_selection_to_data=True)

    Button:
        size_hint_y: None
        text: "print selection"
        on_press: print(LV.adapter.selection)
""")

class MyListItem(ToggleButtonBehavior, SelectableView, BoxLayout):
    name = StringProperty()

    def __repr__(self):
        return "%s(name=%r)" % (type(self).__name__, self.name)

    def on_state(self, me, state):
        print me, state
        if state == "down":
            self.select()
        else:
            self.deselect()
        # self.is_selected = state == "down"

class DataItem(SelectableDataItem):
    def __init__(self, name, **kwargs):
        super(DataItem, self).__init__(**kwargs)
        self.name = name

    def __repr__(self):
        return "%s(name=%r, is_selected=%r)" % (type(self).__name__, self.name, self.is_selected)


class Page(BoxLayout):
    data = ListProperty()

    def __init__(self, **kwargs):
        super(Page, self).__init__(**kwargs)
        self.data = [DataItem("Item {}".format(i), is_selected=True) for i in range(10)]

    def args_converter(self, index, data_item):
        return {
            "index": index,
             "name": data_item.name,
        }


class ExampleApp(App):
    def build(self):
        return Page()


if __name__ == "__main__":
    ExampleApp().run()

      

I am using Kivy v1.9.1-dev


Edit: I worked out how to get all selected records, I updated the code and took that part of the question.

+3


source to share


1 answer


Just in case someone has a question, I am pointing to the correct URL:



You should consider a new RecycleView that has all the functionality you need. Check out an example here: Kivy: An Alternative to Deprecated Features

+1


source







All Articles