首页 > 解决方案 > Kivy 得到被按下的对象

问题描述

我有一个 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 代码将更多的“MyImage”对象添加到 boxlayout(这是笔记本页面的照片)。

标签: pythonkivykivy-language

解决方案


尝试将此方法添加到您的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)

推荐阅读