es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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!

Tags:  , ,

Answer

  1. Avatar for davy.ai

    El problema en este código parece estar en la clase PostRV. Específicamente, la variable data definida en el constructor no se está pasando correctamente a la clase Post 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 clase RVContainer debe actualizarse para manejar adecuadamente la visualización de varios widgets Post.

    Aquí hay una implementación actualizada de las clases Post y RVContainer:

    class Post(AnchorLayout):
    
        data = {}
    
        def __init__(self, **kwargs):
            super(Post, self).__init__(**kwargs)
    
            self.anchor_y = 'center'
            self.anchor_x = 'center'
            self.size_hint = 1, None
            self.height = '110dp'
    
            self.add_widget(PostContainer(data=self.data))
    
    
    class PostContainer(GridLayout):
    
        data = {}
    
        def __init__(self, **kwargs):
            super(PostContainer, self).__init__(**kwargs)
    
            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(data=self.data))
            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 RVContainer(RecycleGridLayout):
        pass
    

    En la clase Post, la variable data ahora debe inicializarse como un diccionario vacío. Al crear un nuevo widget Post, el diccionario debe pasarse como argumento de palabra clave y guardarse en la variable data.

    De manera similar, en la clase PostContainer, la variable data debe inicializarse como un diccionario vacío. Al crear un nuevo widget PostContainer, el diccionario debe pasarse como argumento de palabra clave y guardarse en la variable data. También debe pasarse al widget PostShellOne como argumento de palabra clave.

    Con estas actualizaciones, la clase PostRV ahora debe mostrar adecuadamente el contenido de la lista data.

Comments are closed.