如何设置用户可以使用 Kivy DragBehavior 拖动项目的区域?
How to set area where user can drag items with Kivy DragBehavior?
我是 Kivy 的新手,我正在寻找一种方法来仅在选择的布局内拖动图像,而不是在所有 window 周围。我试图在 kv 文件中使用 drag_rectangle
选项进行操作,但这并没有以预期的行为结束。有什么方法可以设置用户可以拖动项目的区域,如果存在,如何设置?
感谢您的回复。
这是我的代码:
from kivy.config import Config
Config.set('input', 'mouse', 'mouse,disable_multitouch')
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.behaviors import DragBehavior
from kivy.uix.image import Image
class DragLabel(DragBehavior, Image):
pass
class Pattern(FloatLayout):
def create_pattern(self):
A = DragLabel(source="some.png", pos=(0, 0))
self.add_widget(A)
class MainScreen(BoxLayout):
pass
class AberationsApp(App):
def build(self):
return MainScreen()
window = AberationsApp()
window.run()
我的 kv 文件:
<DragLabel>:
drag_rectangle: self.x/10, self.y/10, root.width, root.height
drag_timeout: 10000000
drag_distance: 0
on_touch_move: print(self.x, self.y, self.size)
<Pattern>:
<MainScreen>:
size_hint: 1, 1
Pattern:
size_hint: .8, 1
id: Created_Pattern
Button:
size_hint: .2, 1
text:"Load_points!"
on_press: print(self.size, root.size)
on_release: Created_Pattern.create_pattern()
好的,我解决了这个问题。
我必须了解 DragBehavior 的工作原理。显然,Kivy 网站上有文档,您可以找到与可拖动项目的所有可能交互。
(https://kivy.org/doc/stable/_modules/kivy/uix/behaviors/drag.html)
函数 on_touch_move(self, touch)
解决了我的问题。
此外,我还使用了 Layouts 中的一些方法,以确保我的图像会根据 window.
的大小按比例更改其位置
这是我的代码:
from kivy.config import Config
Config.set('input', 'mouse', 'mouse,disable_multitouch')
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.behaviors import DragBehavior
from kivy.uix.image import Image
from kivy.metrics import sp
class DragLabel(DragBehavior, Image):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.previous_size = [1, 1]
def do_layout(self, *args):
self.x = self.x * self.width / self.previous_size[0]
self.y = self.x * self.height / self.previous_size[1]
if self.x > self.width:
self.x = .85 * self.width
if self.y > self.height:
self.y = .85 * self.height
self.previous_size = [self.width, self.height]
def on_size(self, *args):
self.do_layout()
def on_touch_move(self, touch):
if self._get_uid('svavoid') in touch.ud or \
self._drag_touch is not touch:
return super(DragBehavior, self).on_touch_move(touch) or \
self._get_uid() in touch.ud
if touch.grab_current is not self:
return True
uid = self._get_uid()
ud = touch.ud[uid]
mode = ud['mode']
if mode == 'unknown':
ud['dx'] += abs(touch.dx)
ud['dy'] += abs(touch.dy)
if ud['dx'] > sp(self.drag_distance):
mode = 'drag'
if ud['dy'] > sp(self.drag_distance):
mode = 'drag'
ud['mode'] = mode
if mode == 'drag':
previous_x_position = self.x
previous_y_position = self.y
new_x_position = previous_x_position + touch.dx
new_y_position = previous_y_position + touch.dy
if .85 * self.size[0] >= new_x_position >= 0 and .85 * self.size[1] >= new_y_position >= 0:
self.x = new_x_position
self.y = new_y_position
return True
class Pattern(FloatLayout):
def create_pattern(self):
A = DragLabel(source="some.png", pos=(0, 0))
self.add_widget(A)
class MainScreen(BoxLayout):
pass
class AberationsApp(App):
def build(self):
return MainScreen()
window = AberationsApp()
window.run()
和kv文件:
<DragLabel>:
drag_rectangle: self.x, self.y, root.width, root.height
<Pattern>:
<MainScreen>:
size_hint: 1, 1
Pattern:
size_hint: .8, 1
id: Created_Pattern
Button:
size_hint: .2, 1
text:"Load points!"
on_release: Created_Pattern.create_pattern()
我是 Kivy 的新手,我正在寻找一种方法来仅在选择的布局内拖动图像,而不是在所有 window 周围。我试图在 kv 文件中使用 drag_rectangle
选项进行操作,但这并没有以预期的行为结束。有什么方法可以设置用户可以拖动项目的区域,如果存在,如何设置?
感谢您的回复。
这是我的代码:
from kivy.config import Config
Config.set('input', 'mouse', 'mouse,disable_multitouch')
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.behaviors import DragBehavior
from kivy.uix.image import Image
class DragLabel(DragBehavior, Image):
pass
class Pattern(FloatLayout):
def create_pattern(self):
A = DragLabel(source="some.png", pos=(0, 0))
self.add_widget(A)
class MainScreen(BoxLayout):
pass
class AberationsApp(App):
def build(self):
return MainScreen()
window = AberationsApp()
window.run()
我的 kv 文件:
<DragLabel>:
drag_rectangle: self.x/10, self.y/10, root.width, root.height
drag_timeout: 10000000
drag_distance: 0
on_touch_move: print(self.x, self.y, self.size)
<Pattern>:
<MainScreen>:
size_hint: 1, 1
Pattern:
size_hint: .8, 1
id: Created_Pattern
Button:
size_hint: .2, 1
text:"Load_points!"
on_press: print(self.size, root.size)
on_release: Created_Pattern.create_pattern()
好的,我解决了这个问题。
我必须了解 DragBehavior 的工作原理。显然,Kivy 网站上有文档,您可以找到与可拖动项目的所有可能交互。 (https://kivy.org/doc/stable/_modules/kivy/uix/behaviors/drag.html)
函数 on_touch_move(self, touch)
解决了我的问题。
此外,我还使用了 Layouts 中的一些方法,以确保我的图像会根据 window.
的大小按比例更改其位置这是我的代码:
from kivy.config import Config
Config.set('input', 'mouse', 'mouse,disable_multitouch')
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.behaviors import DragBehavior
from kivy.uix.image import Image
from kivy.metrics import sp
class DragLabel(DragBehavior, Image):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.previous_size = [1, 1]
def do_layout(self, *args):
self.x = self.x * self.width / self.previous_size[0]
self.y = self.x * self.height / self.previous_size[1]
if self.x > self.width:
self.x = .85 * self.width
if self.y > self.height:
self.y = .85 * self.height
self.previous_size = [self.width, self.height]
def on_size(self, *args):
self.do_layout()
def on_touch_move(self, touch):
if self._get_uid('svavoid') in touch.ud or \
self._drag_touch is not touch:
return super(DragBehavior, self).on_touch_move(touch) or \
self._get_uid() in touch.ud
if touch.grab_current is not self:
return True
uid = self._get_uid()
ud = touch.ud[uid]
mode = ud['mode']
if mode == 'unknown':
ud['dx'] += abs(touch.dx)
ud['dy'] += abs(touch.dy)
if ud['dx'] > sp(self.drag_distance):
mode = 'drag'
if ud['dy'] > sp(self.drag_distance):
mode = 'drag'
ud['mode'] = mode
if mode == 'drag':
previous_x_position = self.x
previous_y_position = self.y
new_x_position = previous_x_position + touch.dx
new_y_position = previous_y_position + touch.dy
if .85 * self.size[0] >= new_x_position >= 0 and .85 * self.size[1] >= new_y_position >= 0:
self.x = new_x_position
self.y = new_y_position
return True
class Pattern(FloatLayout):
def create_pattern(self):
A = DragLabel(source="some.png", pos=(0, 0))
self.add_widget(A)
class MainScreen(BoxLayout):
pass
class AberationsApp(App):
def build(self):
return MainScreen()
window = AberationsApp()
window.run()
和kv文件:
<DragLabel>:
drag_rectangle: self.x, self.y, root.width, root.height
<Pattern>:
<MainScreen>:
size_hint: 1, 1
Pattern:
size_hint: .8, 1
id: Created_Pattern
Button:
size_hint: .2, 1
text:"Load points!"
on_release: Created_Pattern.create_pattern()