[英]Add image dynamically inside gridlayout kivy python
I have make a simple user touch to add image using add_widget in gridlayout.我做了一个简单的用户触摸,在 gridlayout 中使用 add_widget 添加图像。 I have done simple prototype.我做了简单的原型。
i press a particular grid and image added always last grid.我按一个特定的网格和图像添加总是最后一个网格。
but i need add image to pressed grid.但我需要将图像添加到按下的网格。
Any suggestions thanks.任何建议谢谢。
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()
The problem is that you are adding the 2.jpg
Image
to the viewclass
of a RecycleView
.问题是您将2.jpg
Image
添加到viewclass
的RecycleView
中。 The function of a RecycleView
is to recycle the viewclass
instances. RecycleView 的RecycleView
是为了回收viewclass
实例。 So if you modify one of those instances, it may show up anywhere in the RecycleGridLayout
, and is likely to move around without respect to the RVItem
that you wanted that modification applied to.因此,如果您修改其中一个实例,它可能会显示在RecycleGridLayout
中的任何位置,并且可能会在不考虑您希望应用该修改的RVItem
的情况下四处移动。
The answer is that whenever you want modify an RVItem
, you must do it using the data
of the RecycleView
.答案是,无论何时要修改RVItem
,都必须使用RecycleView
的data
。 Here is a modified version of your code that adds an image to the canvas
of the RVItem
, by adding an added
key to the data:这是您的代码的修改版本,通过向数据添加added
的密钥,将图像添加到canvas
的RVItem
:
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()
Here is another way to do it by adding an MDCheckBox
to the RVItem
:这是通过将MDCheckBox
添加到RVItem
的另一种方法:
from kivy.properties import BooleanProperty, StringProperty
from kivy.uix.relativelayout import RelativeLayout
from kivymd.app import MDApp
from kivy.lang import Builder
KV_CODE = '''
<RVItem>:
MDCheckbox:
id: cb
active: root.added
size_hint: None, None
size: 50, 50
pos: 0, root.height - self.height
SmartTileWithLabel:
size_hint: None, 1
width: root.width - cb.width
pos: cb.width, 0
text: root.text
source: root.source
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(RelativeLayout):
added = BooleanProperty(False)
text = StringProperty('')
source = StringProperty('')
def on_touch_up(self, touch):
if touch.button == 'left' and self.collide_point(*touch.pos):
# 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
return True
else:
return super(RVItem, self).on_touch_up(touch)
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()
Now the RVItem
is a RelativeLayout
that contains an MDCheckbox
and a SmartTileWithLabel
.现在RVItem
是一个包含MDCheckbox
和SmartTileWithLabel
的RelativeLayout
。 Since the RVItem
is the viewclass
, it must have all the properties that appear as keys in the data, so it has added
, text
, and source
.由于RVItem
是viewclass
,它必须具有在数据中显示为键的所有属性,因此它added
、 text
和source
。 Those properties are used in the KV_CODE
to set the properties of the MDCheckbox
and the SmartTileWithLabel
.这些属性在KV_CODE
中用于设置MDCheckbox
和SmartTileWithLabel
的属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.