在网格布局基维蟒蛇中动态添加图像



我已经做了一个简单的用户触摸,使用网格布局中的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()

问题是您要将2.jpgImage添加到RecycleViewviewclass中。RecycleView的功能是回收viewclass实例。因此,如果您修改其中一个实例,它可能会出现在RecycleGridLayout中的任何位置,并且可能会在不考虑您希望应用该修改的RVItem的情况下四处移动。

答案是每当你想修改一个RVItem,你必须使用RecycleViewdata来完成。下面是代码的修改版本,它通过向数据添加added键,将图像添加到RVItemcanvas

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()

这是另一种方法是通过向RVItem添加MDCheckBox来实现:

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()

现在RVItem是一个包含MDCheckboxSmartTileWithLabelRelativeLayout。由于RVItemviewclass,它必须具有在数据中显示为键的所有属性,因此它具有addedtextsource。这些属性在KV_CODE中用于设置MDCheckboxSmartTileWithLabel的属性。

最新更新