【问题标题】:Drag and drop behaviors in KivyKivy 中的拖放行为
【发布时间】:2020-02-26 10:32:04
【问题描述】:

我是 Python 和 Kivy 的新手。

我的目标是将一个按钮拖到某个地方(标签),每个按钮和标签都有自己的分数,如果我拖动按钮并且我的光标在标签内,它将显示工具提示以显示总和按钮和标签的分数,最后如果我把按钮放在标签上,按钮会自动在标签所在的位置,并打印分数的总和。 但是,如果我将按钮放在标签外,按钮将自动位于按钮所在的位置。

我想在 DragBehavior 中实现一些附加功能:

  • 当我拖动一个按钮时,使其位于其他小部件的顶部。

我已经看过this,但功能对我来说还不够。

这是我的 .py 文件:

from kivy.app import App
from kivy.properties import StringProperty
from kivy.properties import BooleanProperty
from kivy.properties import ObjectProperty
from kivy.core.window import Window
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.behaviors import DragBehavior


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


class DraggableButton(DragBehavior, Button):
    def __init__(self, **kwargs):
        super(DraggableButton, self).__init__(**kwargs)


class DragToHereLabel(HoverBehavior, Label):
    name = StringProperty("")

    def __init__(self, **kwargs):
        super(DragToHereLabel, self).__init__(**kwargs)

    def on_enter(self):
        self.text = "Entered\nScore: 100"

    def on_leave(self):
        self.text = "Leaved\nScore: 100"


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


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

test.kv:

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


<DragToHereLabel>:
    text: "Drag to here\nScore: 100"
    halign: "center"
    canvas.before:
        Color:
            rgba: 0.2, 0.2, 0.2, 1
        Rectangle:
            pos: self.pos
            size: self.size


BoxLayout:
    orientation: "vertical"

    DraggableButton:
        text: "Drag me\nScore: 200"

    DragToHereLabel:

非常感谢您帮助 Kivy 初学者!

【问题讨论】:

    标签: python kivy


    【解决方案1】:

    DraggableButtonon_touch_down()中可以添加;

            parent = self.parent
            parent.remove_widget(self)
            parent.add_widget(self)
    

    这确保DraggableButton 位于其他所有内容之上。

    【讨论】:

    • 非常感谢!但是remove_widgetadd_widget 功能会在我触摸窗口上的“任意位置”时触发,如何解决?
    • 顺便说一句,当我使用on_touch_down 功能时,我不能再拖动按钮了,我该如何解决这个问题?
    • 确保您也致电super(DraggableButton, self).on_touch_down(touch)
    • 谢谢!这其实是我想要的。
    • 触摸未定义得到错误@JohnAnderson
    猜你喜欢
    • 1970-01-01
    • 2016-10-01
    • 2021-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-29
    • 1970-01-01
    相关资源
    最近更新 更多