我有一个使用顶点指令创建的带有矩形和水平线的自定义小组件,我想在小组件中检查用户是否在矩形或水平线内触摸。我想检查用户是否在我的小组件中触碰了矩形或水平线。尝试使用组,但无法找到用户是否触碰了矩形或水平线。请你给我提供线索,请看下面的示例代码。
from kivy.app import App
from kivy.graphics import Line
from kivy.uix.scatter import Scatter
from kivy.uix.relativelayout import RelativeLayout
from kivy.lang import Builder
KV = '''
<Actor>:
id: Actor
canvas:
Color:
rgba: 0,1,0,1
Rectangle:
group: 'rect'
size: 100, 30
pos: 0, root.height - 30
Line:
group: 'line'
points: 50, root.height - 30, 50, 0
width:2
Label:
id: _actr_lbl
text: 'Hello World'
markup: True
color: 0,0,0,1
size_hint: None, None
size: 100, 30
pos: 0, root.height - 30
'''
class Actor(Scatter):
def __init__(self, **kwargs):
super(Actor, self).__init__(**kwargs)
def on_touch_down(self, touch):
print('Touch location {} Actor location {} Actor Size {}'.format(touch, self.pos, self.size))
if self.collide_point(*touch.pos) :
for aVertex in self.canvas.get_group('rect') :
try:
print ('Vertex size {} and pos'.format(aVertex.size, aVertex.pos))
except:
pass
return True
return super(Actor, self).on_touch_down(touch)
class MyPaintApp(App):
def build(self):
Builder.load_string(KV)
root = RelativeLayout()
root.add_widget(Actor(pos_hint={'center_x':0.5, 'center_y':0.5}, size_hint=(.2, 1.)))
return root
if __name__ == '__main__':
MyPaintApp().run()
先谢谢你
你可以做一个简单的边界框检查,但你必须考虑到一个事实,即 touch
是在父坐标系中。所以你可以将触摸位置转换为局部坐标,然后进行测试。下面是一个例子 Rectangle
:
def on_touch_down(self, touch):
print('Touch location {} Actor location {} Actor Size {}'.format(touch, self.pos, self.size))
if self.collide_point(*touch.pos) :
localTouchPos = self.to_local(*touch.pos)
for aVertex in self.canvas.get_group('rect') :
print('\tVertex size {} and pos {}'.format(aVertex.size, aVertex.pos))
intersection = True
if localTouchPos[0] < aVertex.pos[0]:
intersection = False
elif localTouchPos[0] > aVertex.pos[0] + aVertex.size[0]:
intersection = False
if localTouchPos[1] < aVertex.pos[1]:
intersection = False
elif localTouchPos[1] > aVertex.pos[1] + aVertex.size[1]:
intersection = False
print('intersection =', intersection)
return True
return super(Actor, self).on_touch_down(touch)
你也可以做类似的事情 Line
但如果你想做一个普通的 Line
. 如果您的 Line
始终是垂直的,它应该是非常相似的。