我进入了一个需要 Draggable 的 Kivy 项目。
环境:
操作系统:Windows 10 家庭版
Python==3.11.5
基维==2.2.1
kivy-garden-draggable==0.2.0
这是我的 py 和 kv 文件:
lists.py:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.scrollview import ScrollView
from kivy_garden.draggable import KXDraggableBehavior, KXReorderableBehavior
class ListApp(App):
def build(self):
return MainLayout()
class MainLayout(BoxLayout):
pass
class ReorderableBoxLayout(KXReorderableBehavior, BoxLayout):
pass
class Card(KXDraggableBehavior, Label):
pass
ListApp().run()
列表.kv
<ReorderableBoxLayout@KXReorderableBehavior+BoxLayout>
<MainLayout>
canvas.before:
Color:
rgba: .6, .7, .8, 1
Rectangle:
pos: self.pos
size: self.size
BoxLayout:
padding: '10dp'
spacing: '10dp'
ScrollView:
id: left_box
height: self.parent.height
ReorderableBoxLayout:
drag_classes: ['test',]
orientation: 'vertical'
padding: '5dp'
spacing: '10dp'
size_hint_y: None
on_minimum_height: self.height = self.minimum_height
Card:
Card:
ScrollView:
id: center_box
height: self.parent.height
ReorderableBoxLayout:
drag_classes: ['test',]
orientation: 'vertical'
padding: '5dp'
spacing: '10dp'
size_hint_y: None
on_minimum_height: self.height = self.minimum_height
Card:
Card:
ScrollView:
id: right_box
height: self.parent.height
ReorderableBoxLayout:
drag_classes: ['test',]
orientation: 'vertical'
padding: '5dp'
spacing: '10dp'
size_hint_y: None
on_minimum_height: self.height = self.minimum_height
Card:
Card:
<Card>
drag_cls: 'test'
drag_timeout: 0
text: 'Card'
font_size: '30sp'
size_hint_y: None
canvas.before:
Color:
rgba: .5, .8, .5, 1
Rectangle:
pos: self.pos
size: self.size
我正在尝试在 ScrollView 之间移动小部件。我已经放入了三个 SV,它们有一些可拖动的小部件。当我从SV(索引号:2)携带一个小部件时,我可以将其放入SV(1)或SV(0)中,但是当我尝试从SV(1)或SV(0)中使用它时,就会出现问题。当小部件放入的 SV 位于小部件最初所在的 SV 的左侧时,可拖动小部件永远不会进入 SV。
换句话说,
工作:
SV(2) -> SV(1), SV(0)
SV(1) -> SV(0)
从不工作:
SV(0) -> SV(1), SV(2)
SV(1) -> SV(2)
有人知道解决办法吗?
谢谢!
您需要将触摸事件分派给所有 ScrollView,无论其中任何一个 ScrollView 消耗触摸。例如:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy_garden.draggable import KXDraggableBehavior, KXReorderableBehavior
class ListApp(App):
def build(self):
return MainLayout()
class MainLayout(BoxLayout):
pass
class ReorderableBoxLayout(KXReorderableBehavior, BoxLayout):
pass
class Card(KXDraggableBehavior, Label):
pass
class EquitableBoxLayout(BoxLayout):
'''Always dispatches touch events to all its children'''
def on_touch_down(self, touch):
return any([c.dispatch('on_touch_down', touch) for c in self.children])
def on_touch_move(self, touch):
return any([c.dispatch('on_touch_move', touch) for c in self.children])
def on_touch_up(self, touch):
return any([c.dispatch('on_touch_up', touch) for c in self.children])
ListApp().run()
<MainLayout>
canvas.before:
Color:
rgba: .6, .7, .8, 1
Rectangle:
pos: self.pos
size: self.size
EquitableBoxLayout:
padding: '10dp'
spacing: '10dp'
ScrollView:
id: left_box
height: self.parent.height
ReorderableBoxLayout:
drag_classes: ['test',]
orientation: 'vertical'
padding: '5dp'
spacing: '10dp'
size_hint_y: None
on_minimum_height: self.height = self.minimum_height
Card:
Card:
ScrollView:
id: center_box
height: self.parent.height
ReorderableBoxLayout:
drag_classes: ['test',]
orientation: 'vertical'
padding: '5dp'
spacing: '10dp'
size_hint_y: None
on_minimum_height: self.height = self.minimum_height
Card:
Card:
ScrollView:
id: right_box
height: self.parent.height
ReorderableBoxLayout:
drag_classes: ['test',]
orientation: 'vertical'
padding: '5dp'
spacing: '10dp'
size_hint_y: None
on_minimum_height: self.height = self.minimum_height
Card:
Card:
<Card>
drag_cls: 'test'
drag_timeout: 0
text: 'Card'
font_size: '30sp'
size_hint_y: None
canvas.before:
Color:
rgba: .5, .8, .5, 1
Rectangle:
pos: self.pos
size: self.size