【发布时间】:2017-12-02 12:36:07
【问题描述】:
我是 python 和 kivy 的新手,正在与它们斗争。
我想用kivy实现拖放功能(当一个图像被拖到另一个图像并放在它上面时,做一些事情的功能。)。
我想做的是以下三件事;
- 知道用户现在持有的元素的id。
- 知道用户悬停的元素的 ID。
- 知道当用户放下他所拥有的东西时指针下的元素的 ID。
我认为this 对处理它们很有用,所以我写下了下面的python 脚本和.kivy 文件。但是,它并没有按我的预期工作。
有很多问题我不知道如何解决;
- print(self.id) 返回无。
- 即使我只拖动 1 个元素,on_touch_up 也会打印 None 两次。
- 一旦拖放图像,该图像将无法再拖动。
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:
<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"
【问题讨论】:
标签: python python-3.x drag-and-drop kivy kivy-language