KivyMD Dynamic Tab Management dengan 'iterasi' tab yang berbeda

Aug 18 2020

Saya telah menggunakan kode dari dokumen KivyMD tentang 'Manajemen Tab Dinamis' sehingga pengguna dapat menambah / menghapus tab. Namun, masing-masing tab ini yang dibuat jelas identik dan oleh karena itu widget yang saya taruh di dalamnya juga. Ini berarti bahwa jika saya mencoba untuk mengambil id dari widget tersebut dari misalnya Tab 3 , tidak ada cara untuk melakukannya karena ini adalah id yang sama dengan widget di misalnya Tab 1 . Ini kodenya:

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

Tab 1, dengan input di MDTextField adalah 'Hi':

Tab2, di mana input di MDTextField telah diduplikasi dari Tab:

Apakah masih ada pengguna yang masih dapat menambah dan menghapus Tab, tetapi membuatnya sehingga semua widget (seperti MDTextField di file .kv) memiliki id yang berbeda sehingga saya dapat mengakses input pengguna dari mereka? Terima kasih sebelumnya, jika pertanyaan ini dijabarkan dengan buruk, harap tanyakan info lebih lanjut!

Jawaban

1 JohnAnderson Aug 17 2020 at 23:51

The idshanya diisi untuk widget dibuat dalam kvaturan. Jadi apa pun yang Tabdibuat di luar .kvfile tidak akan dimasukkan ke dalam idskamus. Namun, Anda dapat meretasnya idsdengan memodifikasi add_tab()metode Anda :

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)

Ini menambahkan new_idke idsdalam MDTabs.

Untuk membuat MDTextFieldbagian dari Tab, tambahkan saja ke <Tab>aturan. Mungkin seperti ini:

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

Tentu saja, Anda akan menghapus MDTextField(dan lampirannya FloatLayout) dari <AddWorkouts>aturan.