Kivy Recycleview не обновляет добавленные данные

#python #python-3.x #kivy

#python #python-3.x #kivy

Вопрос:

Я снова застрял в своем маленьком проекте Kivy. Идея заключается в том, что приложение перечисляет имена папок из каталога в списке Recycleview. Я хочу иметь возможность добавлять папку с приложением в этот каталог, при этом список обновляется после создания папки.

Отображение списка и создание папок работают. Но мне не удается обновить Recycleview. Я перепробовал все методы, которые я нашел в Интернете, но я думаю, что основная проблема заключается в том, что я, вероятно, не до конца понимаю отношения между различными идентификаторами и как я могу переслать обновленный список в RV. Я знаю, что это было рассмотрено здесь много раз, но я просто не могу понять это.

Большое спасибо всем, кто нашел время, чтобы изучить мою проблему.

Мой сводный файл Python:

 import os
from pathlib import Path
from kivy.app import App
import pathlib
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.properties import ListProperty, StringProperty, ObjectProperty, BooleanProperty
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.popup import Popup
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.boxlayout import BoxLayout

prjct_list = []
prjct_list_clean = []

entries = pathlib.Path.home() / 'Desktop' / 'Troubleshootdir'

def get_all_files(entries):
    prjct_list = []
    global prjct_list_clean
    file_iterator = entries.iterdir()
    for entry in sorted(file_iterator):
        if entry.is_dir():
            prjct_list.append(entry.name)
            prjct_list_clean = list(filter(lambda x: x.startswith(''), prjct_list))
    return prjct_list_clean

class MessageBox(Popup):

    def popup_dismiss(self):
        self.dismiss()

class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior, RecycleBoxLayout):
    """ Adds selection and focus behaviour to the view. """
    selected_value = StringProperty('')
    btn_info = ListProperty(prjct_list_clean)

class SelectableButton(RecycleDataViewBehavior, Button, Widget):
    """ Add selection support to the Label """
    index = None
    selected = BooleanProperty(False)
    selectable = BooleanProperty(True)

    def refresh_view_attrs(self, rv, index, data):
        """ Catch and handle the view changes """
        self.index = index
        return super(SelectableButton, self).refresh_view_attrs(rv, index, data)


#############################################   RV   #############################################
class RV(RecycleView):
    rv_layout = ObjectProperty(None)

    def __init__(self, **kwargs):
        global prjct_list_clean
        get_all_files(entries)
        super(RV, self).__init__(**kwargs)
        self.data = []
        for subject in prjct_list_clean:
            self.data.append({'text':subject})
        rv = self.ids['rv_layout']
        rv.data = self.data

    def callback(self, text):
        self.ids.con_wksp.text  = text

class Manager(Widget):
    new_wksp = ObjectProperty(None)

    def cre_wksp(self):
        path = Path(entries, 'Prfx_'   self.new_wksp.text, "Subfolder01/Subfolder02")
        os.makedirs(path, exist_ok=True)
        path = Path(entries, 'Prfx_'   self.new_wksp.text, "01_"   self.new_wksp.text   ".APN", 'Subfolder02')
        os.makedirs(path, exist_ok=True)

class TroubleshootApp(BoxLayout, App,):
    def build(self):
        self.recycl = RV()
        self.add_widget(self.recycl)
        self.mnager = Manager()
        self.add_widget(self.mnager)
        return self

    def update_dir(self):
        get_all_files(entries)
        self.recycl.ids.rv_layout.data = prjct_list_clean

if __name__ == "__main__":
    TroubleshootApp().run()
 

Мой файл .kv:

 #:kivy 2.0.0

<SelectableButton>:
    # Draw a background to indicate selection
    background_color: [153 / 255.0, 153 / 255.0, 153 / 255.0, 255 / 255.0]
    canvas.before:
        Color:
            rgba: [230 / 255.0, 115 / 255.0, 0 / 255.0, 255 / 255.0]
        Rectangle:
            pos: self.pos
            size: self.size

<RV>:
    #rv_layout: rv_layout
    bar_width: 0
    viewclass: 'SelectableButton'
    SelectableRecycleBoxLayout:
        id: rv_layout
        default_size: None, dp(56)
        default_size_hint: 0.9, None
        size_hint_y: None
        height: self.minimum_height
        orientation: "vertical"

<Manager>:

    new_wksp: new_wksp

    FloatLayout:
        pos: 0, 0
        size: root.width, root.height

        Button:
            text: 'Create Folder'
            x: root.x * 1.1
            top: self.height and root.y   root.height * 0.5
            size_hint: 0.8, 0.15
            on_press:
                root.cre_wksp()

        TextInput:
            id: new_wksp
            x: root.x * 1
            top: self.height and root.y   root.height * 0.9
            size_hint: 1, 0.15
            padding: 0, (self.height-self.line_height)/2
            halign: 'center'
 

Ответ №1:

Вы должны добавить новую папку к своим RV данным. Просто добавьте вызов update_dir() в конце вашего cre_wksp() метода:

 def cre_wksp(self):
    path = Path(entries, 'Prfx_'   self.new_wksp.text, "Subfolder01/Subfolder02")
    os.makedirs(path, exist_ok=True)
    path = Path(entries, 'Prfx_'   self.new_wksp.text, "01_"   self.new_wksp.text   ".APN", 'Subfolder02')
    os.makedirs(path, exist_ok=True)
    App.get_running_app().update_dir()
 

С некоторыми изменениями в update_dir() методе:

 def update_dir(self):
    get_all_files(entries)
    data = []
    for subject in prjct_list_clean:
        data.append({'text':subject})
    self.recycl.data = data
 

Комментарии:

1. Джон, еще раз большое спасибо за вашу помощь. Это сделало свое дело и сделало многие вещи намного понятнее для меня прямо сейчас. Ваша помощь действительно ценится!