KivyMD Dynamic Tab Management avec différentes "itérations" d'onglets

Aug 18 2020

J'ai utilisé le code des documents KivyMD sur la "Gestion dynamique des onglets" afin que les utilisateurs puissent ajouter/supprimer des onglets. Cependant, chacun de ces onglets qui sont créés sont évidemment identiques et donc les widgets que j'y mets le sont aussi. Cela signifie que si j'essaie de prendre l'identifiant dudit widget à partir , par exemple, de l'onglet 3 , il n'y a aucun moyen de le faire car il s'agit du même identifiant que le widget dans, par exemple, l'onglet 1 . Voici le code :

fichier .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]
    )

fichier .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()

Onglet 1, où l'entrée dans MDTextField est 'Hi' :

Tab2, où l'entrée dans MDTextField a été dupliquée à partir de Tab :

Existe-t-il de toute façon que les utilisateurs puissent toujours ajouter et supprimer des onglets, mais faire en sorte que tous les widgets (comme le MDTextField dans le fichier .kv) aient des identifiants différents afin que je puisse accéder à l'entrée de l'utilisateur ? Merci d'avance, si cette question a été mal formulée, n'hésitez pas à demander plus d'informations !

Réponses

1 JohnAnderson Aug 17 2020 at 23:51

Les idsne sont renseignés que pour les widgets créés dans une kvrègle. Ainsi, tout fichier Tabcréé en dehors du .kvfichier ne sera pas entré dans le idsdictionnaire. Cependant, vous pouvez les pirater en idsmodifiant votre add_tab()méthode :

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)

Cela ajoute le new_idau idsdans le MDTabs.

Pour faire la MDTextFieldpartie du Tab, il suffit de l'ajouter à la <Tab>règle. Peut-être comme ça :

<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()

Bien sûr, vous supprimeriez le MDTextField(et son encadrement FloatLayout) de la <AddWorkouts>règle.