Connor
Connor

Reputation: 63

Draggable Image in Kivy

So I am new to Kivy and Gui coding in general.... I am trying to have a moveable image, and here is the code I have so far tried:

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.image import Image
from kivy.uix.behaviors import DragBehavior
from kivy.uix.floatlayout import FloatLayout 

class Box_layout(FloatLayout):
    def __init__(self,**kwargs):
        super(Box_layout, self).__init__(**kwargs)
        self.size_hint = (.50,.50)
        self.orientation = "vertical"
        self.add_widget(MoveableImage())#drag_rectangle = [self.x, self.y, self.width, self.height],source="temp_plot.png"))


class MoveableImage(DragBehavior,Image):

    def __init__(self, **kwargs):
        super(MoveableImage, self).__init__(**kwargs)
        self.drag_timeout = 10000000
        self.drag_distance = 0
        #self.drag = DragBehavior()
        #self.drag.drag_rectangle = [self.x, self.y, self.width, self.height]

        
class gameApp(App):
    def build(self):
        wimg = MoveableImage(source="temp_plot.png")
        m = Box_layout()



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

What happens is I currently have a blank 'image' that is draggable on the first click, but then reaches a timeout or something where it cannot be moved after it has been moved once..... I figured it was a timeout issue or something though self.drag_timeout = 10000000 did not fix the issue...what am I doing wrong here? Further, when I am passing an actual source to MoveableImage, ie self.add_widget(MoveableImage(source='tmp.png')), the image never is moveable to begin with, which again is very confusing to me....if someone could help and explain what is going on and then explain why these behaviors are occurring, hat would be awesome!

Upvotes: 0

Views: 708

Answers (1)

John Anderson
John Anderson

Reputation: 38822

You also need to keep the drag_rectangle of the MoveableImage updated. The easiest way to do that is by using the kv language. So your MoveableImage class can be simply:

class MoveableImage(DragBehavior, Image):
    pass

Then load a kv rule like this:

kv = '''
<MoveableImage>:
    # Define the properties for the MoveableImage
    drag_rectangle: self.x, self.y, self.width, self.height
    drag_timeout: 10000000
    drag_distance: 0
'''
Builder.load_string(kv)

The advantage of using kv here is that it automatically sets up bindings that you would otherwise have to code up yourself. The drag_rectangle is an example of that, so when the MoveableImage is moved (dragged), the drag_rectangle is automatically updated.

If you want to set up those bindings yourself (and not use kv), yu can define your MoveableImage as:

class MoveableImage(DragBehavior, Image):

    def __init__(self, **kwargs):
        super(MoveableImage, self).__init__(**kwargs)
        self.drag_timeout = 10000000
        self.drag_distance = 0
        self.drag_rectangle = [self.x, self.y, self.width, self.height]

    def on_pos(self, *args):
        self.drag_rectangle = [self.x, self.y, self.width, self.height]

    def on_size(self, *args):
        self.drag_rectangle = [self.x, self.y, self.width, self.height]

Upvotes: 2

Related Questions