pythonuser-interfacekivykivy-recycleview

Kivy RecycleView data widgets showing up on top of each other


Im trying to make the list of this custom widgets be in a vertical list above and below each other but they all appear in the same pos.

Im not sure where im going wrong. I'vw tried a few little things that I could thnk of, but clearly, to no solution.

I'm new to kivy so any tips you may have would be awesome.

scrathapp.py

import os
import kivy
import random
import time
from pytube import YouTube, Playlist, Search
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.gridlayout import GridLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.image import Image
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.properties import ObjectProperty, StringProperty, NumericProperty, ListProperty, BooleanProperty
from kivy.logger import Logger
from kivy.config import Config

Config.set('graphics', 'resizable', True)



class YT_Widget(Widget):
    yt = None
    has_yt = BooleanProperty(False)
    title = StringProperty()
    author = StringProperty()
    length = StringProperty()
    
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        Logger.info("USE: YT_Widget")
        self.title = "title"
        self.author = "channel"
        self.length = "0"

    def add_yt(self, yt_obj):
        if isinstance(yt_obj, YouTube):
            self.yt = yt_obj
            if not self.has_yt:
                self.has_yt = True

    def on_has_yt(self, instance, value):
        Logger.info(f"\n***********\n type(value):{str(value)}\n***********\n")
        if self.has_yt:
            self.title = self.yt.title
            self.author = self.yt.author
            self.length = str(format(self.yt.length / 60, ".2f"))
    
    def get_yt(self):
            if not self.has_yt:
                search = Search("fatheranarchy")
                res = search.results
                iyt = random.choice(res)
                self.add_yt(iyt)
            return self.yt



class YT_List(RecycleView):
    yt_data = ListProperty([])
    
    def addData(self, yt_list):
        self.yt_data = [{"self.yt":item} for item in yt_list]
        self.refresh_from_data()




class MainBox(BoxLayout):
    def do_it(self):
        sch = Search("death cab for cutie")
        self.ids.yts.addData(sch.results)



class ScratchApp(App):
    def build(self):
        Logger.info("Start: Started App")
        return MainBox()


if __name__ == "__main__":
    scr = ScratchApp()
    scr.run()

scratch.kv

#:kivy 2.0.0

<YLabel@Label>:
    font_size:12

<YT_Widget>:
    BoxLayout:
        size:300,50
#        canvas.before:
#            Color:
#                rgba: (0.1, 0.5, 0.7, 1)
#            Rectangle:
#                size:self.size
#                pos:self.pos
        BoxLayout:
            Button:
                id:yt_btn
                size_hint: 0.09, 1.0
                text:""
                background_normal: "images/grn_btn.png"
                background_down: "images/red_btn.png"
                on_press:root.get_yt()
#                Image:
#                    id:yt_btn_img
#                    size:self.parent.width, self.parent.height
#                    source:
#                    center_x:self.parent.center_x
#                    center_y:self.parent.center_y
            GridLayout:
                rows:2
                size_hint: 0.91, 1.0
                BoxLayout:
                    size_hint: 0.91, 0.5
                    YLabel:
                        id:yt_title
                        text:root.title
                BoxLayout:
                    size_hint: 0.91, 0.5
                    YLabel:
                        id:yt_author
                        text:root.author
                    YLabel:
                        id:yt_length
                        text:root.length


<YT_List>:
    viewclass:"YT_Widget"
#    orientation: "vertical"
    spacing: 40
    padding:10, 10
#    space_x: self.size[0]/3
    RecycleBoxLayout:
        color:(0, 0.7, 0.4, 0.8)
        default_size: None, dp(56)
        default_size_hint: 0.4, None 
        size_hint_y: None
        height: self.minimum_height
        orientation: 'vertical'


<MainBox>:
    orientation:"vertical"
    Button:
        id:butt
        text:"search"
        on_press:root.do_it()
    YT_List:
        id:yts
        data:self.yt_data

Solution

  • I got it working correctly. All I did was change some of the layout stuff in the .kv file. I'll post some of the .kv below. The only real change I made in the .py was changing the YT_Widget to extend from the BoxLayout class instead of a FloatLayout, not sure if it had any effect on this problem.

    Anyways, the situtation has been corrected. Thanks. :)

    <YT_Widget>:
        Button:
            id:yt_btn
            size_hint: 0.09, 1.0
            text:""
            background_normal: "images/grn_btn.png"
            background_down: "images/red_btn.png"
            on_press:root.get_yt()
        GridLayout:
            rows:2
            size_hint: 0.91, 1.0
            BoxLayout:
                size_hint: 0.91, 0.5
                YLabel:
                    id:yt_title
                    text:root.title
            BoxLayout:
                size_hint: 0.91, 0.5
                YLabel:
                    id:yt_author
                    text:root.author
                YLabel:
                    id:yt_length
                    text:root.length