KJG
KJG

Reputation: 113

KIVY DragBehavior Custom Widget

I am trying to use DragBehavior to help in moving my custom widget across RelativeLayout. Find below sample code. Why my widget is not moving on Drag action please. For simplicity I had included only rectangle in my custom widget MyPaintWidget

from kivy.app import App
from kivy.graphics import Line
from kivy.uix.scatter import Scatter
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.behaviors import DragBehavior
from kivy.lang import Builder
from kivy.graphics import Color, Rectangle

Builder.load_string("""
<MyPaintWidget>:
    # Define the properties for the DragLabel
    drag_rectangle: self.x, self.y, self.width, self.height
    drag_timeout: 10000000
    drag_distance: 0
""")


class MyPaintWidget(DragBehavior, Scatter):

    def __init__(self, **kwargs) :
        self.selected = None
        self.touched = False
        super(MyPaintWidget, self).__init__(**kwargs)

    def create_figure(self,  **kwargs):
        print ('position is {}'.format(self.pos))
        print ('width Height {}'.format(self.to_parent(self.width, self.height)))
        self.canvas.add(Rectangle(pos  = self.pos, size = self.size))
        return self

    def on_touch_move(self, touch):
        print('Started to move x: {} y: {}'.format(touch.x, touch.y))
        return super(MyPaintWidget, self).on_touch_move(touch)


class MyPaintApp(App):

    def build(self):
        parent = RelativeLayout()
        self.painter = MyPaintWidget(pos_hint={"center_x": 0.5, 'center_y':0.5}, size_hint=(.2,.1))

        parent.add_widget(self.painter.create_figure())
        return parent

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

Upvotes: 0

Views: 95

Answers (1)

John Anderson
John Anderson

Reputation: 39072

The DragBehavior works by adjusting the pos of your MyPaintWidget, but you have set pos_hint on the MyPaintWidget. The pos_hint takes precedence over pos, so while the drag changes pos, it is ignored because there is a pos_hint. Also, the Rectangle that you draw in create_figure has its size and pos set when that method is called, and there is no mechanism to change it when the MyPaintWidget is moved. So, even if the Widget was being dragged, the Rectangle would not move.

Here is a version of your code with those problems corrected:

from kivy.app import App
from kivy.uix.scatter import Scatter
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.behaviors import DragBehavior
from kivy.lang import Builder

Builder.load_string("""
<MyPaintWidget>:
    # Define the properties for the DragLabel
    drag_rectangle: self.x, self.y, self.width, self.height
    drag_timeout: 10000000
    drag_distance: 0
    canvas:
        Color:
            rgba: 1,0,0,1
        Rectangle:
            pos: 0,0  # only do this for RelativeLayout
            size: self.size
""")


class MyPaintWidget(DragBehavior, Scatter):

    def __init__(self, **kwargs) :
        self.selected = None
        self.touched = False
        super(MyPaintWidget, self).__init__(**kwargs)

    def on_touch_move(self, touch):
        print('Started to move x: {} y: {}'.format(touch.x, touch.y))
        return super(MyPaintWidget, self).on_touch_move(touch)


class MyPaintApp(App):

    def build(self):
        parent = RelativeLayout()
        self.painter = MyPaintWidget( pos=(240, 200), size_hint=(.2,.1))

        parent.add_widget(self.painter)
        return parent

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

Upvotes: 1

Related Questions