Kivy Recycleview。在运动事件上​​更改标签背景颜色

时间:2019-09-09 17:39:36

标签: kivy

是否可以更改无触摸事件的背景颜色?请参考下面的代码。 self.collidepoint()方法始终返回False。我知道即使返回True也不起作用,因为我应该clear RV.data并用新的bcolor重新构建它,这似乎很慢。

代码

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
from kivy.core.window import Window
Builder.load_string('''
<SelectableLabel>:
    # Draw a background to indicate selection
    bcolor:  root.bcolor
    canvas.before:
        Color:
            rgba: (0, 0, 0, 1) if self.selected else self.bcolor
        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: True
        touch_multiselect: True
''')


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)
    bcolor = (0,0,0,1)

    def __init__(self, **kwargs):
        super(SelectableLabel, self).__init__(**kwargs)

        Window.bind(mouse_pos=self.light_up)

    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 light_up(self, window, mouse_pos):

        print('MOTION ', mouse_pos, self.collide_point(mouse_pos[0], mouse_pos[1]))
        if self.collide_point(mouse_pos[0], mouse_pos[1]):
            self.bcolor = (1,1,1,1)

        else:
            self.bcolor = (0, 0, 0, 1)

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()
        Window.bind(on_motion=SelectableLabel.on_motion())

if __name__ == '__main__':
    TestApp().run()

1 个答案:

答案 0 :(得分:1)

您的代码有两个问题。我已经发布了您的代码版本,其中包含我认为对这些问题的更正。

首先是partitionC中的bcolor必须是SelectableLabel(否则ListProperty绑定将无效)。

第二个是在您的kv方法中,您必须将窗口坐标转换为适合传递给light_up()的坐标。为此,我在每个collide_point()中保存了对RV实例的引用(为SelectableLabel)。然后使用self.root进行坐标转换。

此外,to_local()方法中的Window.bind()也是不必要的。

build()