我如何取消选择之前在 kivy recycleview 中选择的行
how can i deselect a previously selected row in kivy recycleview
我需要帮助在带有 SelectableLabel 视图的 RecycleView 中取消选择选定的 Label Item。
有什么解决办法吗?
我知道它应该写在 'def apply_selection' 的某个地方,但我无法让它工作
示例:
我希望能够在选定的行上执行另一次单击,然后选择将被删除。
我认为代码应该放在这里:
def apply_selection(self, rv, index, is_selected):
''' Respond to the selection of items in the view. '''
self.selected = is_selected
我尝试使用第三个输入来指定当前选择,但它并没有真正起作用。
1. 这个方法是我需要修改的地方以实现我之后的目标吗?
2. 如果是这样,有什么正确的方法吗?
常见问题解答
Do you want to be able to multi-select rows, and then deselect
individual row? – ikolim Sep 30 '18 at 21:04
no just select in one press and deselect in another press on a line
,but also keep the selection changing when selecting different lines.
maybe its easier to say that im looking for listview behavior in this
recycleview – amihai Sep 30 '18 at 21:07
解决方案
以下解决方案不适用于 multi-select
。
如果行未被选中则设置选中,或者当它已被选中时取消选中。
片段
def apply_selection(self, rv, index, is_selected):
''' Respond to the selection of items in the view. '''
self.selected = not self.selected
例子
main.py
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
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:
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
''')
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 = not self.selected
class RV(RecycleView):
def __init__(self, **kwargs):
super(RV, self).__init__(**kwargs)
self.data = [{'text': str(x)} for x in range(100)]
class TestApp(App):
def build(self):
return RV()
if __name__ == '__main__':
TestApp().run()
输出
下面的代码执行要求的操作,即
- 一次只启用一个选择并且
- 启用取消选择所选项目
它与第一个答案的代码相同,除了突出显示的 3 个不同之处
** 差异 **。
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
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:
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
multiselect: False # ** DIFFERENCE **
touch_multiselect: False # ** DIFFERENCE **
''')
class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior,
RecycleBoxLayout):
''' Adds selection and focus behaviour to the view. '''
# required to authorise unselecting a selected item
touch_deselect_last = BooleanProperty(True) # ** DIFFERENCE **
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 = not self.selected
class RV(RecycleView):
def __init__(self, **kwargs):
super(RV, self).__init__(**kwargs)
self.data = [{'text': str(x)} for x in range(100)]
class RVMainApp(App):
def build(self):
return RV()
if __name__ == '__main__':
RVMainApp().run()
我需要帮助在带有 SelectableLabel 视图的 RecycleView 中取消选择选定的 Label Item。 有什么解决办法吗?
我知道它应该写在 'def apply_selection' 的某个地方,但我无法让它工作
示例:
我希望能够在选定的行上执行另一次单击,然后选择将被删除。
我认为代码应该放在这里:
def apply_selection(self, rv, index, is_selected):
''' Respond to the selection of items in the view. '''
self.selected = is_selected
我尝试使用第三个输入来指定当前选择,但它并没有真正起作用。 1. 这个方法是我需要修改的地方以实现我之后的目标吗? 2. 如果是这样,有什么正确的方法吗?
常见问题解答
Do you want to be able to multi-select rows, and then deselect individual row? – ikolim Sep 30 '18 at 21:04
no just select in one press and deselect in another press on a line ,but also keep the selection changing when selecting different lines. maybe its easier to say that im looking for listview behavior in this recycleview – amihai Sep 30 '18 at 21:07
解决方案
以下解决方案不适用于 multi-select
。
如果行未被选中则设置选中,或者当它已被选中时取消选中。
片段
def apply_selection(self, rv, index, is_selected):
''' Respond to the selection of items in the view. '''
self.selected = not self.selected
例子
main.py
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
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:
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
''')
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 = not self.selected
class RV(RecycleView):
def __init__(self, **kwargs):
super(RV, self).__init__(**kwargs)
self.data = [{'text': str(x)} for x in range(100)]
class TestApp(App):
def build(self):
return RV()
if __name__ == '__main__':
TestApp().run()
输出
下面的代码执行要求的操作,即
- 一次只启用一个选择并且
- 启用取消选择所选项目
它与第一个答案的代码相同,除了突出显示的 3 个不同之处 ** 差异 **。
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
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:
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
multiselect: False # ** DIFFERENCE **
touch_multiselect: False # ** DIFFERENCE **
''')
class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior,
RecycleBoxLayout):
''' Adds selection and focus behaviour to the view. '''
# required to authorise unselecting a selected item
touch_deselect_last = BooleanProperty(True) # ** DIFFERENCE **
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 = not self.selected
class RV(RecycleView):
def __init__(self, **kwargs):
super(RV, self).__init__(**kwargs)
self.data = [{'text': str(x)} for x in range(100)]
class RVMainApp(App):
def build(self):
return RV()
if __name__ == '__main__':
RVMainApp().run()