Fed_Dragon
Fed_Dragon

Reputation: 1368

Kivy execute function when widget is dragged

I have a little demo here:

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

The problem is, I want to call my on_drag method when the DraggableButton is dragged.

Also, I only want the mouse position while in the function, so I can remove the line
Window.bind(mouse_pos=lambda w, p: setattr(self.button, "mouse_pos", p))

Is there any solution to this?

Upvotes: 0

Views: 81

Answers (1)

furas
furas

Reputation: 142671

It uses DragBehavior so I found source code for DragBehavior
and I see it has method on_touch_move(touch).

I replaced this method in DraggableButton() and when button is moved then it gets MouseMotionEvent with pos which seems to be mouse position.

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()

Result:

[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)
---

Upvotes: 1

Related Questions