KIVY collide_point 顶点矩形
KIVY collide_point vertex Rectangle
我有一个带有矩形和水平线的自定义小部件,它们都是使用顶点指令创建的。我想检查用户是否在我的小部件中的矩形或水平线内触摸。尝试使用组但无法找到用户是否触摸了矩形或线。你能给我提供线索吗?
找到下面的示例代码。
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
总是垂直的,它应该非常相似。
我有一个带有矩形和水平线的自定义小部件,它们都是使用顶点指令创建的。我想检查用户是否在我的小部件中的矩形或水平线内触摸。尝试使用组但无法找到用户是否触摸了矩形或线。你能给我提供线索吗? 找到下面的示例代码。
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
总是垂直的,它应该非常相似。