在Kivy中使用DragBehavior [英] usage of DragBehavior in Kivy

查看:107
本文介绍了在Kivy中使用DragBehavior的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是python和kivy的新手,并在其中挣扎。

I'm new for python and kivy, and struggling with them.

我想实现拖放功能(当图像被拖动到

I wanted to implement drag and drop function (a function that when a image is dragged to another image and dropped on it, do something.) with kivy.

我想做的是以下三件事;

What I want to do are the following three things;


  • 知道用户现在一直持有的元素的ID。

  • 知道用户正在停留的元素的ID。

  • 知道用户放下所拥有内容时指针下的元素的ID。

我认为对于解决这些问题很有用,所以我写下了下面的python脚本和.kivy文件。但是,它并没有达到我的预期。

I thought this would be useful to deal with them, so I wrote down the python script and .kivy file following. However, it dosen't work as I intended.

有许多我不知道如何解决的问题;

there are many problems which I don't know how to solve;


  • print(self.id)返回None。

  • 即使我只拖动1个元素,on_touch_up也不打印两次。

  • 一旦拖放图像,就无法再拖动图像。

python文件:

from kivy.app import App
from kivy.uix.image import Image
from kivy.uix.behaviors import DragBehavior
from kivy.properties import BooleanProperty
from kivy.properties import ObjectProperty
from kivy.factory import Factory
from kivy.core.window import Window


class HoverBehavior(object):
    """Hover behavior.
    :Events:
        `on_enter`
            Fired when mouse enter the bbox of the widget.
        `on_leave`
            Fired when the mouse exit the widget
    """

    hovered = BooleanProperty(False)
    border_point = ObjectProperty(None)
    '''Contains the last relevant point received by the Hoverable. This can
    be used in `on_enter` or `on_leave` in order to know where was dispatched the event.
    '''

    def __init__(self, **kwargs):
        self.register_event_type('on_enter')
        self.register_event_type('on_leave')
        Window.bind(mouse_pos=self.on_mouse_pos)
        super(HoverBehavior, self).__init__(**kwargs)

    def on_mouse_pos(self, *args):
        if not self.get_root_window():
            return  # do proceed if I'm not displayed <=> If have no parent
        pos = args[1]
        # Next line to_widget allow to compensate for relative layout
        inside = self.collide_point(*self.to_widget(*pos))
        if self.hovered == inside:
            # We have already done what was needed
            return
        self.border_point = pos
        self.hovered = inside
        if inside:
            self.dispatch('on_enter')
        else:
            self.dispatch('on_leave')

    def on_enter(self):
        pass

    def on_leave(self):
        pass


Factory.register('HoverBehavior', HoverBehavior)


class DraggableImage(DragBehavior, HoverBehavior, Image):
    def __init__(self, **args):
        super(DraggableImage, self).__init__(**args)
        self.source_file = ""
        self.is_on_hover = False

    def on_enter(self):
        self.source_file = self.source
        self.source = "green.png"
        self.is_on_hover = True
        print(self.id)

    def on_leave(self):
        self.source = self.source_file
        self.is_on_hover = False
        print(self.id)

    def on_touch_up(self, touch):
        if self.is_on_hover:
            print(self.id)


class TestApp(App):
    def build(self):
        pass


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

test.kivy:

test.kivy:

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

BoxLayout:
    orientation: "horizontal"
    DraggableImage:
        id: "left_left"
        source: "red.png"
    DraggableImage:
        id: "left_right"
        source: "yellow.png"
    DraggableImage:
        id: "right_left"
        source: "red.png"
    DraggableImage:
        id: "right_right"
        source: "yellow.png"


推荐答案

创建<以code> StringProperty 命名,例如 name 。不要使用id,因为id在kv中使用。

如此更改您的班级和kv:

Create a StringProperty named, name for example. Don't use id, because id is used in kv.
Change your class and kv as so:

from kivy.properties import StringProperty

class DraggableImage(DragBehavior, HoverBehavior, Image):

    name = StringProperty("")

    def __init__(self, **args):
        super(DraggableImage, self).__init__(**args)
        self.source_file = ""
        self.is_on_hover = False

    def on_enter(self):
        self.source_file = self.source
        self.source = "green.png"
        self.is_on_hover = True
        print(self.name)

    def on_leave(self):
        self.source = self.source_file
        self.is_on_hover = False
        print(self.name)

    def on_touch_up(self, touch):
        if self.is_on_hover:
            print(self.name)




KV = """

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

BoxLayout:
    orientation: "horizontal"
    DraggableImage:
        name: "left_left"
        source: "red.png"
    DraggableImage:
        name: "left_right"
        source: "yellow.png"
    DraggableImage:
        name: "right_left"
        source: "red.png"
    DraggableImage:
        name: "right_right"
        source: "yellow.png"

"""

这篇关于在Kivy中使用DragBehavior的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆