如何在缩略图库中创建可点击的Kivy图片

3

我正在尝试通过有趣的项目学习kivy,但是很难掌握kivy处理事情的方式。

在Tkinter中,我使用for循环创建了缩略图库,并将每个单独的图像绑定到回调函数,只是将点击的图像的信息(路径)传递给回调函数以打开图像。但我似乎无法理解如何在kivy中做这么简单的事情,所以我需要一些帮助。

使用Button小部件可以工作;我尝试创建一个包含按钮的图库并将它们的背景更改为图像,但图像被拉伸和扭曲(不是我想要的结果)。

因此,我用Image小部件制作了缩略图库,缩略图显示得非常好,但是我找不到一种方法来将单击的缩略图信息传递给每个缩略图的回调(回调事件)以正常工作。

我使用on_touch_down属性将每个缩略图绑定,但当执行回调时,所有缩略图的信息都在一个单击中传递给回调函数,这不是我想要的结果,我只希望传递被单击的缩略图的信息。我阅读了kivy文档,但越来越困惑。以下是我的代码,请帮帮我,非常感谢。

from kivy.app import App 
from kivy.uix.gridlayout import GridLayout
from kivy.uix.image import Image 

import glob


class Image_Gallery(GridLayout):


    def __init__(self):
        super(Image_Gallery, self).__init__()
        images = glob.glob('C:\Users\Public\Pictures\Sample Pictures\*.jpg')  # windows 7 sample pictures dir looks great
        self.cols=3
        for img in images:
            thumb = Image(source=img)
            thumb.bind(on_touch_down=self.callback)    # I tried on_touch property but does not work with images only buttons
            self.add_widget(thumb)

    def callback(self, obj, touch):
        # This should print only the clicked image source. 
        # (but instead is printing all images sources at once)
        print obj.source                



class mainApp(App):


    def build(self):
        return Image_Gallery()


if __name__ == '__main__':
    mainApp().run()
1个回答

9

on_touch 事件会在应用程序中的所有小部件上分派事件,您需要定义自己的 Image 类并重新定义 on_touch 方法:

...
class MyImage(Image):
    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            print self.source

class Image_Gallery(GridLayout):

    def __init__(self, **kwargs):
        super(Image_Gallery, self).__init__(**kwargs)
        images = glob.glob('C:\Users\Public\Pictures\Sample Pictures\*.jpg')
        self.cols = 3
        for img in images:
            thumb = MyImage(source=img)
            self.add_widget(thumb)
...

2
非常感谢回答,我想指出,这是由(SP SP)的回答让我理解了。非常感谢!现在为了更清楚地阐述。类“class MyImage(Image)”变成了kivy Image()类,所以这就解释了为什么你要将 source ='img.jpg' 传递给这个新创建的类。自定义类中的部分 “if self.collide_point (* touch.pos):” 成为过滤器,该部分仅过滤掉已单击或选择的图像(小部件),否则,如(SP SP)所说,所有图像(小部件)的来源都将被打印。 太好了! - Diego Suarez
小注释,这是可能的,使用像 OP 尝试过的绑定。我使用 partial 函数,可以将参数组合到函数中 - 其中之一是对它绑定的图像的引用。所以我的单击函数可以在实际图像上调用 collide_point。但即使它起作用了,也相当笨重,并且还有一些其他问题 - 所以我最终只是按照您的答案来子类化图像。 - John C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接