拖动小部件时,Kivy 执行函数

Kivy execute function when widget is dragged

我这里有一个小演示:

From DemoApp.py:

from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.behaviors import DragBehavior
from kivy.core.window import Window


class DraggableButton(DragBehavior, Button):
    def on_drag(self, *args):
        ...


class DemoLayout(FloatLayout):
    def __init__(self, **kwargs):
        super(DemoLayout, self).__init__(**kwargs)
        self.add_widget(DraggableButton(text='Drag Me'))


class DemoApp(App):
    def build(self):
        self.button= DraggableButton(text='Drag Me')
        Window.bind(mouse_pos=lambda w, p: setattr(self.button, "mouse_pos", p))
        return self.button


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

From demo.kv:

<DraggableButton>:
    drag_rectangle: self.x, self.y, self.width, self.height
    drag_timeout: 10000000
    drag_distance: 0

问题是,我想在拖动 DraggableButton 时调用我的 on_drag 方法。

此外,我只想要函数中的鼠标位置,所以我可以删除行
Window.bind(mouse_pos=lambda w, p: setattr(self.button, "mouse_pos", p))

有什么解决办法吗?

它使用 DragBehavior 所以我找到了 DragBehavior
的源代码 我看到它有方法 on_touch_move(touch).

我在 DraggableButton() 中替换了这个方法,当按钮被移动时,它得到 MouseMotionEventpos,这似乎是鼠标位置。

from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.behaviors import DragBehavior
from kivy.core.window import Window


class DraggableButton(DragBehavior, Button):
    def on_touch_move(self, touch):  
        super().on_touch_move(touch)  # run original `on_touch_move()`
        
        print('[on_drag] touch:', touch)
        
        #print('[on_drag] touch.dpos:', touch.dpos)
        #print('[on_drag] touch.spos:', touch.spos)
        print('[on_drag] touch.pos:', touch.pos)

        print('---')


class DemoApp(App):
    def build(self):
        self.button = DraggableButton(text='Drag Me')
        return self.button


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

结果:

[on_drag] touch: <MouseMotionEvent spos=(0.36, 0.5766666666666667) pos=(288.0, 346.0)>
[on_drag] touch.pos: (288.0, 346.0)
---
[on_drag] touch: <MouseMotionEvent spos=(0.35875, 0.5783333333333334) pos=(287.0, 347.0)>
[on_drag] touch.pos: (287.0, 347.0)
---
[on_drag] touch: <MouseMotionEvent spos=(0.35875, 0.5783333333333334) pos=(287.0, 347.0)>
[on_drag] touch.pos: (287.0, 347.0)
---