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()
谢谢!
快速解决方案
我相信最简单的方法是迭代回收框中的元素,如果选择了它们,则取消选择它们并将文本设置为""
.请考虑在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
向TestView
类添加一个selected
属性,允许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
从
<TestView>
中删除不需要的属性(text_selected
、name_selected
(:<TestView>: viewclass: 'SelectableLabel'