如何解决如何阻止Kivy在RecycleView中以模数自动选择项目?
情况:以下代码使用Kivy的RecycleView类生成显示数据表的GUI。该表的每一行都以红色的“忽略”按钮开头,用户可以通过单击其颜色来在红色和绿色之间切换。
问题::当我单击一行的“忽略”按钮时,它不仅使单击的按钮变成绿色,还将许多其他按钮也变绿色。不需要的选择是周期性发生的,也就是说,每个 n 按钮都变成绿色。
为什么会这样?我如何才能让Kivy停止这样做,而是选择 only 单击的按钮?
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import BooleanProperty
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.recycleview.views import RecycleDataViewBehavior
Builder.load_string('''
<Row@BoxLayout>:
orientation: 'horizontal'
data: [None,None,None]
IgnoreButton:
text: 'Ignored' if self.selected else 'Ignore'
background_normal: ''
# color green if ignored,otherwise red
background_color: [0.2,0.5,0.1,1] if self.selected else [0.5,1]
Label:
text: str(root.data[1])
Label:
text: str(root.data[2])
Label:
text: str(root.data[3])
<RV>:
viewclass: 'Row'
data: [{'data':[0,x,x+1,x+2]} for x in range(100)]
SelectableRecycleBoxLayout:
orientation: 'vertical'
default_size: None,dp(56)
default_size_hint: 1,None
size_hint_y: None
height: self.minimum_height
multiselect: True
''')
class SelectableRecycleBoxLayout(FocusBehavior,LayoutSelectionBehavior,RecycleBoxLayout):
' Adds selection and focus behaviour to the view. '
class IgnoreButton(Button,RecycleDataViewBehavior):
# Add selection support to the Button.
index = None
selected = BooleanProperty(False)
selectable = BooleanProperty(True)
def on_touch_down(self,touch):
# Add selection on touch down.
if super().on_touch_down(touch):
self.selected = not self.selected
class RV(RecycleView):
def __init__(self,**kwargs):
super().__init__(**kwargs)
class TestApp(App):
def build(self):
return RV()
if __name__ == '__main__':
TestApp().run()
解决方法
有了Recycleview,您可以看到的小部件数量就很多……它们被回收了。因此,您不能依赖小部件来存储状态。
在Row中,我创建了一个NumericProperty idx,并在rvdata列表中创建了一个索引。这对应于“虚拟小部件”的索引。
我创建了一个列表来存储ToggleButton的状态。
您将按钮像ToggleButton一样对待,所以我将其替换为ToggleButton。您可以重新添加颜色更改。
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import NumericProperty,ListProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.recycleview import RecycleView
Builder.load_string('''
<Row>:
orientation: 'horizontal'
data: [None,None,None]
ToggleButton:
text: 'Ignored' if app.root.selected[root.idx] == 'normal' else 'Ignore'
#background_normal: ''
# color green if ignored,otherwise red
#background_color: [0.2,0.5,0.1,1] if app.root.selected[root.idx] == 'normal' else [0.5,1]
state: app.root.selected[root.idx]
on_state: app.root.selected[root.idx] = self.state
Label:
text: str(root.data[1])
Label:
text: str(root.data[2])
Label:
text: str(root.data[3])
<RV>:
viewclass: 'Row'
data: [{'data':[0,x,x+1,x+2],'idx': x} for x in range(100)]
RecycleBoxLayout:
orientation: 'vertical'
default_size: None,dp(56)
default_size_hint: 1,None
size_hint_y: None
height: self.minimum_height
''')
class Row(BoxLayout):
idx = NumericProperty()
class RV(RecycleView):
selected = ListProperty(['normal'] * 100)
class TestApp(App):
def build(self):
return RV()
if __name__ == '__main__':
TestApp().run()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。