奇异果多选框 [英] Kivy multiple selection with checkboxes
问题描述
我正在尝试使用Kivy创建一个视图,该视图具有默认情况下全部选中的选项列表,并且用户可以选择取消选择某些条目(通过单击复选框或该行的任何位置).>
单击行项目的标签部分有效,但是我注意到单击复选框不会更改选择,我无法解决该选择(我尝试了几种不同的状态绑定,我将它们留了下来在示例代码中被注释掉了)
这是一个简单的例子,展示了我的尝试.
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()
我正在使用Kivy v1.9.1-dev
编辑:我研究了如何预先选择所有条目,我更新了代码并删除了问题的那一部分.
以防万一有人提出我指向正确网址的问题:
您应该考虑使用具有所需所有功能的新RecycleView.在此处查看示例: Kivy:替代不推荐使用的功能 >
I'm trying to create a view using Kivy that has a list of options that are all selected by default, and the user can choose to deselect some entries (by clicking on the checkbox or anywhere on the row).
Clicking on the label part of the row item works, but I noticed that clicking on the checkbox doesn't change the selection which I can't work out how to solve (I tried a few different state bindings, I left them commented out in the example code)
Here is 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'm using Kivy v1.9.1-dev
Edit: I worked out how to get all the entries pre-selected, I've updated the code and took that part of the question out.
Just in case someone else has the the question I point to the right url:
You should consider the new RecycleView, which has all the functionality you request. Look here for a sample: Kivy: alternative to deprecated features
这篇关于奇异果多选框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!