Teniendo problemas con los datos de Kivy RecycleView.
Estoy teniendo un problema extraño al usar RecycleView de Kivy. Cuando intento pasar una lista de diccionarios usando un widget personalizado que hice como la viewclass, parece crear el número correcto de widgets, pero los valores reales no parecen pasar, lo que resulta en un número correcto de widgets “predeterminados”. Aquí hay un ejemplo ejecutable que hice del problema que estoy teniendo:
main.py:
from kivy.app import App
import view
class MainApp(App):
def build(self):
return view.PostRV()
if __name__ == 'main':
app = MainApp()
app.run()
main.kv:
<rvcontainer>:
multiselect: True
touch_multiselect: True
height: self.minimum_height
cols: 1
default_size_hint: 1, None
default_size: None, dp(110)
size_hint_y: None
view.py:
from kivy.uix.recycleview import RecycleView
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.gridlayout import GridLayout
from kivy.graphics import Color, RoundedRectangle
from kivy.core.window import Window
from kivy.properties import StringProperty
from kivy.uix.recyclegridlayout import RecycleGridLayout
class PostRV(RecycleView):
def __init__(self, **var_args):
super(PostRV, self).__init__(**var_args)
self.data = [
{'date': 'una fecha', 'time': 'una hora', 'name': 'un nombre'},
{'date': 'otra fecha', 'time': 'otra hora', 'name': 'otro nombre'}
] # estos datos no parecen pasar apropiadamente
self.add_widget(RVContainer())
self.size_hint = 1, 1
self.viewclass = Post
class RVContainer(RecycleGridLayout):
pass
# debajo de esta línea esta el widget personalizado "Post" el cual dividí en múltiples clases para un control y claridad más fácil
class Post(AnchorLayout):
date = StringProperty('')
time = StringProperty('')
name = StringProperty('')
def __init__(self, **var_args):
super(Post, self).__init__(**var_args)
self.anchor_y = 'center'
self.anchor_x = 'center'
self.size_hint = 1, None
self.height = '110dp'
self.add_widget(PostContainer(date=self.date, time=self.time, name=self.name))
class PostContainer(GridLayout):
date = StringProperty('')
time = StringProperty('')
name = StringProperty('')
def __init__(self, **var_args):
super(PostContainer, self).__init__(**var_args)
self.cols = 2
self.padding = '12dp'
self.size_hint = (None, None)
self.width = Window.size[0] / 1.05
self.height = '100dp'
self.add_widget(PostShellOne(date=self.date, time=self.time, name=self.name))
self.add_widget(PostShellTwo())
self.bind(pos=self.update_rect, size=self.update_rect)
with self.canvas.before:
Color(1, 1, 1, .7)
self.rect = RoundedRectangle(size=self.size, pos=self.pos, radius=[10])
def update_rect(self, *args):
self.rect.pos = self.pos
self.rect.size = self.size
self.width = Window.size[0] / 1.05
class PostShellOne(GridLayout):
date = StringProperty('')
time = StringProperty('')
name = StringProperty('')
def __init__(self, **var_args):
super(PostShellOne, self).__init__(**var_args)
self.rows = 3
name_label = Label(text=self.name, color=(0, 0, 0, 1))
date_label = Label(text=self.date, color=(0, 0, 0, 1))
time_label = Label(text=self.time, color=(0, 0, 0, 1))
self.add_widget(name_label)
self.add_widget(time_label)
self.add_widget(date_label)
class PostShellTwo(Button):
def __init__(self, **var_args):
super(PostShellTwo, self).__init__(**var_args)
self.text = 'botón'
self.background_color = (0, 0, 0, 0)
self.background_normal = ''
self.bind(pos=self.update_rect, size=self.update_rect)
with self.canvas.before:
Color(0, 0, 0, .4)
self.rect = RoundedRectangle(size=self.size, pos=self.pos, radius=[40])
def update_rect(self, *args):
self.rect.pos = self.pos
self.rect.size = self.size
Cualquier ayuda es apreciada, ¡gracias!
davy.ai
El problema en este código parece estar en la clase
PostRV
. Específicamente, la variabledata
definida en el constructor no se está pasando correctamente a la clasePost
para su visualización.Para solucionar este problema, la clase
Post
debe actualizarse para aceptar un argumento de diccionario y mostrar adecuadamente su contenido. Además, la claseRVContainer
debe actualizarse para manejar adecuadamente la visualización de varios widgetsPost
.Aquí hay una implementación actualizada de las clases
Post
yRVContainer
:En la clase
Post
, la variabledata
ahora debe inicializarse como un diccionario vacío. Al crear un nuevo widgetPost
, el diccionario debe pasarse como argumento de palabra clave y guardarse en la variabledata
.De manera similar, en la clase
PostContainer
, la variabledata
debe inicializarse como un diccionario vacío. Al crear un nuevo widgetPostContainer
, el diccionario debe pasarse como argumento de palabra clave y guardarse en la variabledata
. También debe pasarse al widgetPostShellOne
como argumento de palabra clave.Con estas actualizaciones, la clase
PostRV
ahora debe mostrar adecuadamente el contenido de la listadata
.