python-3.xkivyscreenkivymdnestedrecyclerview

add recycle view item to another screen from a recycle view- kivy


I have two screens. MainScreen and Playlist. MainScreen has a RecycleView method added that displays list of items. These items are created from folder names(directories). I want the files inside each folder(directories) to open on the Playlist Screen depending on which directory name is clicked.

I intend to clear the screen immediately after the user leaves the screen.

from kivymd.app import MDApp
from kivymd.uix.button import MDFlatButton, MDRectangleFlatButton
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.recycleview import RecycleView
from kivy.uix.screenmanager import ScreenManager, Screen
from kivymd.uix.screen import MDScreen

from pathlib import Path, PurePath

# Music Path
storageLocation = Path.cwd()
if Path('Books').is_dir():
    storageLocation = Path.cwd() / 'Books'

class RecycleViewRow(BoxLayout):
    text = StringProperty()


class MainScreen(MDScreen):
    def __init__(self, **kwargs):
        super(MainScreen, self).__init__(**kwargs)

        booksdir = [f for f in storageLocation.iterdir() if f.is_dir()]
        self.children[0].data = [{'text': str(x), 'id': str(x)} for x in booksdir]
       # print(self.children[0].data)

class Playlist(MDScreen):
    def on_pre_enter(self, *args):
        self.ids.Box.clear_widgets()
        #self.ids.Box.add_widget(MDRectangleFlatButton(text="done", ))
        print(self.manager.ids)
        return


class Main(MDApp):
    def build(self):
        sm = ScreenManager()
        sm.add_widget(MainScreen(name='MainScreen'))
        sm.add_widget(Playlist(name='Playlist'))
        sm.add_widget(Test(name="Test"))
        return sm  
Main().run()

.kv

<RecycleViewRow>:
    orientation: 'vertical'

    Button:
        text: root.text
        #on_press: app.root.message_box(root.text)
        on_release:app.root.current = 'Playlist'

<MainScreen>:


    RecycleView:
        id: rv
        viewclass: 'RecycleViewRow'
        RecycleBoxLayout:
            default_size: None, dp(56)
            default_size_hint: 1, None
            size_hint_y: None
            height: self.minimum_height
            orientation: 'vertical'


<Playlist>
    BoxLayout:
        orientation: 'vertical'
        id:Box

    

Solution

  • You can trigger a method from your RecycleViewRow, like this:

    <RecycleViewRow>:
        orientation: 'vertical'
    
        Button:
            text: root.text
            on_release: app.fill_playlist(root.text)
    

    Then, the the fill_playlist() method. you can fill the PlayList:

    def fill_playlist(self, dir):
        self.root.current = 'Playlist'  # this also clears the play list
        playlist = self.root.get_screen('Playlist')
        for sub in os.listdir(dir):
            playlist.ids.Box.add_widget(MDRectangleFlatButton(text=sub))