[英]Kivy accessing dynamically created TextInput inside a GridLayout
[英]Add image dynamically inside 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()
問題是您將2.jpg
Image
添加到viewclass
的RecycleView
中。 RecycleView 的RecycleView
是為了回收viewclass
實例。 因此,如果您修改其中一個實例,它可能會顯示在RecycleGridLayout
中的任何位置,並且可能會在不考慮您希望應用該修改的RVItem
的情況下四處移動。
答案是,無論何時要修改RVItem
,都必須使用RecycleView
的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()
這是通過將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()
現在RVItem
是一個包含MDCheckbox
和SmartTileWithLabel
的RelativeLayout
。 由於RVItem
是viewclass
,它必須具有在數據中顯示為鍵的所有屬性,因此它added
、 text
和source
。 這些屬性在KV_CODE
中用於設置MDCheckbox
和SmartTileWithLabel
的屬性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.