首页 > 解决方案 > 在gridlayout kivy python中动态添加图像

问题描述

我做了一个简单的用户触摸,在 gridlayout 中使用 add_widget 添加图像。我做了简单的原型。

我按一个特定的网格和图像添加总是最后一个网格。

但我需要将图像添加到按下的网格。

任何建议谢谢。

from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.uix.image import Image
from kivymd.uix.imagelist import SmartTileWithLabel
KV_CODE = '''
RecycleView:
    viewclass: 'RVItem'
    RecycleGridLayout:
        #orientation: 'vertical'
        cols:2
        size_hint_y: None
        height: self.minimum_height
        default_size_hint: 1, None
        default_size: 100,300
        spacing: 20
        padding: 10
'''
class RVItem(SmartTileWithLabel):
    def on_release(self):
        image=Image(source='2.jpg')
        self.add_widget(image,index=-1, canvas='before')

class SampleApp(MDApp):
    def build(self):
        return Builder.load_string(KV_CODE)
    def on_start(self):
        rv = self.root
        rv.data = ({'text': str(i), } for i in range(5))
SampleApp().run()

标签: pythonkivy

解决方案


问题是您正在将a添加2.jpg Image到. a 的作用是回收实例。因此,如果您修改其中一个实例,它可能会出现在 , 中的任何位置,并且可能会在不考虑您希望应用该修改的情况下四处移动。viewclassRecycleViewRecycleViewviewclassRecycleGridLayoutRVItem

答案是,无论何时要修改RVItem,都必须使用dataRecycleView。这是您的代码的修改版本,它通过向数据添加键来向 的canvas中添加图像:RVItemadded

from kivy.properties import BooleanProperty
from kivymd.app import MDApp
from kivy.lang import Builder
from kivymd.uix.imagelist import SmartTileWithLabel

KV_CODE = '''
<RVItem>:
    canvas:
        # uncomment these lines to get a black background behind the checkbox
        # Color:
        #     rgba: 0,0,0,1
        # Rectangle:
        #     size: 32, 32
        #     pos: self.x, self.y + self.height - 32
        Color:
            rgba: 1,1,1,1
        Rectangle:
            size: 32, 32
            pos: self.x, self.y + self.height - 32
            source: 'atlas://data/images/defaulttheme/checkbox_on' if self.added else 'atlas://data/images/defaulttheme/checkbox_off'

RecycleView:
    viewclass: 'RVItem'
    RecycleGridLayout:
        #orientation: 'vertical'
        cols:2
        size_hint_y: None
        height: self.minimum_height
        default_size_hint: 1, None
        default_size: 100,300
        spacing: 20
        padding: 10
'''


class RVItem(SmartTileWithLabel):
    added = BooleanProperty(False)

    def on_release(self):
        # find this item in the data
        root = MDApp.get_running_app().root
        data = root.data
        for d in data:
            if d['text'] == self.text:
                # found this item, change `added` to opposite
                d['added'] = not d['added']
                root.refresh_from_data()
                break


class SampleApp(MDApp):

    def build(self):
        return Builder.load_string(KV_CODE)

    def on_start(self):
        rv = self.root
        rv.data = ({'text': str(i), 'source':'1.jpg', 'added':False } for i in range(5))


SampleApp().run()

推荐阅读