ScreenTest是一个屏幕,其中包含:
- 带可选标签的视图
- 根据所选标签而变化的标签
- 重置按钮
重置按钮应该重置视图中的选择,但我不知道如何选择SelectableLabel,然后将其“is_selected”设置为False。没有我可以访问的id或类来更改此参数
我需要的是,通过单击重置按钮,视图中没有任何内容被选中,因此标签中没有显示文本(或文本被重置为“”,因为text_selected为空)。
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import BooleanProperty
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.label import Label
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
from kivy.uix.screenmanager import ScreenManager, Screen
Builder.load_string("""
<ScreenTest>:
BoxLayout:
TestView:
id: test_view
Label:
id: text_lbl
text: "" if not test_view.text_selected else test_view.text_selected
Button:
id: reset_btn
on_press: print("Wow")
<TestView>:
viewclass: 'SelectableLabel'
text_selected: ''
name_selected: ''
SelectableRecycleBoxLayout:
id: culture_sub_view_layout
orientation: 'vertical'
default_size: None, dp(32)
default_size_hint: .6, None
size_hint: 1, .9
multiselect: False
touch_multiselect: False
<SelectableLabel>:
# Draw a background to indicate selection
canvas.before:
Color:
rgba: (.05, 0.5, .9, .8) if self.selected else (.5, .5, .5, 1)
Rectangle:
pos: self.pos
size: self.size
""")
class TestView(RecycleView):
def __init__(self, **kwargs):
super(TestView, self).__init__(**kwargs)
self.data = [
{"text": "Test1", "description": "Test1.text"},
{"text": "Test2", "description": "Test2.text"},
{"text": "Test3", "description": "Test3.text"}
]
class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior,
RecycleBoxLayout):
pass
class SelectableLabel(RecycleDataViewBehavior, Label):
index = None
selected = BooleanProperty(False)
selectable = BooleanProperty(True)
def refresh_view_attrs(self, rv, index, data):
self.index = index
return super(SelectableLabel, self).refresh_view_attrs(
rv, index, data)
def on_touch_down(self, touch):
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):
self.selected = is_selected
if is_selected:
print("selection changed to {0}".format(rv.data[index]))
rv.name_selected = rv.data[index]['text']
rv.text_selected = rv.data[index]['description']
else:
print("selection removed for {0}".format(rv.data[index]))
class ScreenTest(Screen):
pass
sm = ScreenManager()
sm.add_widget(ScreenTest(name='menu'))
class TestApp(App):
def build(self):
return sm
test_app = TestApp()
test_app.run()
谢谢!
答案 0 :(得分:1)
我认为最简单的方法是迭代回收框中的元素,如果选中它们则取消选择它们并将文本设置为""
。考虑在TestView
类中声明的以下函数:
def remove_selection(self):
# Remove text
self.parent.children[1].text = ""
# Remove selection
for child in self.children[0].children:
if child.selected:
child.selected = False
当然,您必须在按下按钮时调用它,您可以将布局更改为:
Button:
id: reset_btn
on_press: test_view.remove_selection()
在更复杂的布局中,给孩子和家长打电话会变得非常混乱,所以我想建议一种更清洁的方法来解决你的问题。由于您一次只处理1个选定的项目,我认为最好的方法是将项目本身存储在您的程序中,并在需要时从中检索信息。确切地说,您可以简单地存储所选项目,而不是在name_selected
中存储text_selected
和test_view
。要做到这一点,必须引入一些变化:
导入ObjectProperty
和StringProperty
:
from kivy.properties import BooleanProperty, ObjectProperty, StringProperty
在selected
课程中添加TestView
属性,允许None
有助于检查是否有任何内容被选中:
class TestView(RecycleView):
selected = ObjectProperty(None, allownone=True)
编辑上面提到的remove_selection
方法:
def remove_selection(self):
# Remove selection
if self.selected is not None:
self.selected.selected = False
self.selected = None
将text_selected
和name_selected
属性添加到SelectableLabel
类:
class SelectableLabel(RecycleDataViewBehavior, Label):
index = None
selected = BooleanProperty(False)
selectable = BooleanProperty(True)
text_selected = StringProperty()
name_selected = StringProperty()
修改apply_selection
方法:
def apply_selection(self, rv, index, is_selected):
self.selected = is_selected
if is_selected:
print("selection changed to {0}".format(rv.data[index]))
# Store selected text and name inside the label
self.name_selected = rv.data[index]['text']
self.text_selected = rv.data[index]['description']
# Remember the selection
rv.selected = self
else:
print("selection removed for {0}".format(rv.data[index]))
更改text_lbl
中显示的文字:
Label:
id: text_lbl
text: "" if test_view.selected is None else test_view.selected.text_selected
从text_selected
移除不需要的属性(name_selected
,<TestView>
):
<TestView>:
viewclass: 'SelectableLabel'