KivyMD 的悬停行为不准确

Inaccurate hover behavior with KivyMD

我正在使用 Kivy 和 KivyMD,运行在将 Kivy RecycleView 与 KivyMD HoverBehavior 组合时遇到问题。发生的事情是我列表中的底部元素(在回收视图内)以我期望的方式表现在悬停行为上,正确检测鼠标何时进入和退出列表元素的边界框。但是,当我在列表中向上移动时,被检测为悬停的元素离我的鼠标指针实际所在的位置越来越远。

例如,当悬停在 10 个元素中的第 10 个元素上时,悬停行为的 on_enter 和 on_leave 方法正确显示了这一点,但我必须将鼠标悬停在元素 8 上才能获取元素 9待检测,6得到8待检测,以此类推。

这是我目前拥有的代码,已尽可能精简以便能够重现该问题。您可以安装依赖项(Kivy 和 KivyMD)和 运行 代码。从那里开始,尝试将鼠标悬停在列表中的各种元素上,注意错误的复选框是如何被选中的,以及错误的元素编号是如何输出到控制台的。

可能是什么导致了这种行为?

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, StringProperty
from kivymd.uix.behaviors import HoverBehavior
from kivy.uix.relativelayout import RelativeLayout

Builder.load_string('''
<RV>:
    viewclass: 'TestItem'
    RecycleBoxLayout:
        default_size: None, dp(56)
        default_size_hint: 1, None
        size_hint_y: None
        height: self.minimum_height
        orientation: 'vertical'

<TestItem>:
    canvas:
        Color:
            rgba: .8, .8, .8, 1
        Line:
            points: 0,0,self.width,0
            width:1 
    CheckBox:
        id: "checkbox"
        active: True if root.status == 'completed' else False
    Label:
        size_hint_x: .86
        text: root.title
''')

class TestItem(RecycleDataViewBehavior, RelativeLayout, HoverBehavior):
    ''' Add selection support to the Label '''
    status = StringProperty()
    title = StringProperty()

    def on_enter(self, *args):
        self.children[1].background_checkbox_normal ="atlas://data/images/defaulttheme/checkbox_on"
        print("Entering", self.title)

    def on_leave(self, *args):
        self.children[1].background_checkbox_normal ="atlas://data/images/defaulttheme/checkbox_off"
        print("Leaving", self.title)

class RV(RecycleView):
    def __init__(self, **kwargs):
        super(RV, self).__init__(**kwargs)
        self.data = [{'title': str(x), 'status': "not started"} for x in range(10)]
        self.refresh_from_data()

class TestApp(App):
    def build(self):
        return RV()

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

HoverBehavior 似乎无法在 RelayiveLayout 上正常工作。尝试改变

class TestItem(RecycleDataViewBehavior, RelativeLayout, HoverBehavior):

class TestItem(RecycleDataViewBehavior, HoverBehavior, FloatLayout):

这还需要重构 kv 中的 <TestItem> 规则。类似于:

<TestItem>:
    canvas:
        Color:
            rgba: .8, .8, .8, 1
        Line:
            points: self.x, self.y,self.width,self.y
            width:1 
    CheckBox:
        id: "checkbox"
        size_hint_x: .14
        pos_hint: {'x': 0.86}
        center_y: root.center_y
        active: True if root.status == 'completed' else False
    Label:
        size_hint_x: .86
        pos_hint: {'x': 0}
        center_y: root.center_y
        text: root.title