我有一个Kivy应用程序,其中有一个滚动视图。在这个滚动视图中,有一个容纳了大量图片的boxlayout,并且在整个运行过程中不断变化(可以在任何时候从1到300)。当一个触屏事件发生时,我需要知道用户在哪个图像上按了一下(也就是说他们当时在哪个图像上,因为他们可以上下滚动),甚至需要得到相对于图像而不是整个屏幕的按压坐标(我需要在他们按压的地方画画,如果不知道他们在哪个图像上按了一下,在哪里按了一下,我就无法做到这一点)。如何才能做到这一点呢?
kv文件中是这样定义的。
MyScrollView:
bar_color: [1, 0, 0, 1]
id: notebook_scroll
padding: 0
spacing: 0
do_scroll: (False, True) # up and down
BoxLayout:
padding: 0
spacing: 0
orientation: 'vertical'
id: notebook_image
size_hint: 1, None
height: self.minimum_height
MyImage:
<MyImage>:
source: 'images/notebook1.png'
allow_stretch: True
keep_ratio: False
size: root.get_size_for_notebook()
size_hint: None, None
它基本上是一个无限的笔记本 在运行时,python代码会在boxlayout中添加更多的 "MyImage "对象(这是笔记本页面的照片)。
试着将此方法添加到你的应用程序中 MyImage
:
def to_image(self, x, y):
''''
Convert touch coordinates to pixels
:Parameters:
`x,y`: touch coordinates in parent coordinate system - as provided by on_touch_down()
:Returns: `x, y`
A value of None is returned for coordinates that are outside the Image source
'''
# get coordinates of texture in the Canvas
pos_in_canvas = self.center_x - self.norm_image_size[0] / 2., self.center_y - self.norm_image_size[1] / 2.
# calculate coordinates of the touch in relation to the texture
x1 = x - pos_in_canvas[0]
y1 = y - pos_in_canvas[1]
# convert to pixels by scaling texture_size/source_image_size
if x1 < 0 or x1 > self.norm_image_size[0]:
x2 = None
else:
x2 = self.texture_size[0] * x1/self.norm_image_size[0]
if y1 < 0 or y1 > self.norm_image_size[1]:
y2 = None
else:
y2 = self.texture_size[1] * y1/self.norm_image_size[1]
return x2, y2
然后你可以添加一个 on_touch_down()
对你的 MyImage
类。
def on_touch_down(self, touch):
if self.collide_point(*touch.pos):
print('got a touch on', self, 'at', touch.pos, ', at image pixels:', self.to_image(*touch.pos))
return True
else:
return super(MyImage, self).on_touch_down(touch)