KivyMD Dynamic Tab Management con diverse "iterazioni" di schede

Aug 18 2020

Ho utilizzato il codice dei documenti KivyMD sulla "Gestione dinamica delle schede" in modo che gli utenti possano aggiungere/eliminare schede. Tuttavia, ognuna di queste schede create è ovviamente identica e quindi lo sono anche i widget che ho inserito. Ciò significa che se sto cercando di prendere l'id di detto widget da ad esempio Tab 3 , non c'è un modo per farlo in quanto è lo stesso id del widget ad esempio Tab 1 . Ecco il codice:

file .py

def on_start(self):
    self.add_tab()

def get_tab_list(self):
    print(self.root.ids.addworkouts.ids.tabs.get_tab_list())

def add_tab(self):
    self.index += 1
    self.root.ids.addworkouts.ids.tabs.add_widget(Tab(text=f"Exercise {self.index}"))

def remove_tab(self):
    self.index -= 1
    self.root.ids.addworkouts.ids.tabs.remove_widget(
        self.root.ids.addworkouts.ids.tabs.get_tab_list()[0]
    )

file .kv

<AddWorkouts>
name: 'AddWorkouts'
tabs: tabs

BoxLayout:
    orientation: 'vertical'

    MDToolbar:
        title: ' '#app.getWorkoutName()
        type: 'top'
        left_action_items: [['keyboard-backspace', lambda x: app.goBacktoMyWorkouts()]]
        #md_bg_color: app.theme_cls.accent_color
        elevation: 10


    FloatLayout:
        canvas:
            Color:
                rgba: 0, 0, 0.5, 0.9
            Rectangle:
                pos: self.pos
                size: self.size

        MDTabs:
            id: tabs

        FloatLayout:
            canvas:
                Color:
                    rgba: 1, 1, 1, 1
                Rectangle:
                    size: self.size
                    pos: self.pos

            pos_hint: {'center_x': 0.5, 'y': 0.1}
            size_hint: 0.8, 0.6


            MDTextField:
                pos_hint: {'x': 0.05, 'y': 0.8}
                size_hint: 0.6, None
                hint_text: 'Exercise Name'
                helper_text_mode: 'on_focus'
                required: 'True'
                multiline: False


<Tab>

    MDList:

        MDBoxLayout:
            adaptive_height: True
            md_bg_color: 1, 1, 1, 1

            MDFlatButton:
                text: "ADD EXERCISE"
                text_color: 16/255, 167/255, 249/255, 1
                on_release: app.add_tab()

            MDFlatButton:
                text: "REMOVE LAST EXERCISE"
                text_color: 16/255, 167/255, 249/255, 1
                on_release: app.remove_tab()

Scheda 1, dove l'input in MDTextField è 'Ciao':

Tab2, dove l'input in MDTextField è stato duplicato da Tab:

Esiste comunque la possibilità per gli utenti di aggiungere ed eliminare schede, ma fare in modo che tutti i widget (come MDTextField nel file .kv) abbiano ID diversi in modo da poter accedere all'input dell'utente da loro? Grazie in anticipo, se questa domanda è stata formulata male per favore basta chiedere maggiori informazioni!

Risposte

1 JohnAnderson Aug 17 2020 at 23:51

Vengono idspopolati solo per i widget creati in una kvregola. Pertanto, qualsiasi elemento Tabcreato al di fuori del .kvfile non verrà inserito nel idsdizionario. Tuttavia, puoi hackerarli idsmodificando il tuo add_tab()metodo:

import weakref
def add_tab(self):
    self.index += 1
    new_tab = Tab(text=f"Exercise {self.index}")
    new_id = 'tab_' + str(self.index)
    self.root.ids.addworkouts.ids.tabs.add_widget(new_tab)
    self.root.ids.addworkouts.ids.tabs.ids[new_id] = weakref.ref(new_tab)

Questo aggiunge il new_idal idsnel file MDTabs.

Per creare la MDTextFieldparte di Tab, basta aggiungerla alla <Tab>regola. Forse così:

<Tab>
    MDList:
        MDTextField:
            size_hint: 0.6, None
            hint_text: 'Exercise Name'
            helper_text_mode: 'on_focus'
            required: 'True'
            multiline: False

        MDBoxLayout:
            adaptive_height: True
            md_bg_color: 1, 1, 1, 1

            MDFlatButton:
                text: "ADD EXERCISE"
                text_color: 16/255, 167/255, 249/255, 1
                on_release: app.add_tab()

            MDFlatButton:
                text: "REMOVE LAST EXERCISE"
                text_color: 16/255, 167/255, 249/255, 1
                on_release: app.remove_tab()

Ovviamente, rimuoveresti MDTextField(e il suo allegato FloatLayout) dalla <AddWorkouts>regola.