在 kivy 中重置可选标签

  • 本文关键字:标签 kivy kivy
  • 更新时间 :
  • 英文 :


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_selectedtext_selected存储在test_view中,不如简单地存储所选项目。为此,必须引入许多更改:

  1. 导入ObjectPropertyStringProperty

    from kivy.properties import BooleanProperty, ObjectProperty, StringProperty
    
  2. TestView类添加一个selected属性,允许None这将有助于检查是否选择了任何内容:

    class TestView(RecycleView):
    selected = ObjectProperty(None, allownone=True)
    
  3. 编辑我上面提到的remove_selection方法:

    def remove_selection(self):
    # Remove selection
    if self.selected is not None:
    self.selected.selected = False
    self.selected = None
    
  4. text_selectedname_selected属性添加到SelectableLabel类:

    class SelectableLabel(RecycleDataViewBehavior, Label):
    index = None
    selected = BooleanProperty(False)
    selectable = BooleanProperty(True)
    text_selected = StringProperty()
    name_selected = StringProperty()
    
  5. 编辑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]))
    
  6. 更改text_lbl中显示的文本:

    Label:
    id: text_lbl
    text: "" if test_view.selected is None else test_view.selected.text_selected
    
  7. <TestView>中删除不需要的属性(text_selectedname_selected(:

    <TestView>:
    viewclass: 'SelectableLabel'
    

最新更新