[Python] Add widgets to MDTabsCarousel dynamically in KivyMD

Discussão em 'Python' iniciado por Stack, Maio 4, 2025.

  1. Stack

    Stack Membro Participativo

    Taking inspiration from the MDTabsCarousel example, I am trying to add tabs and content to the MDTabsPrimary and MDTabsCarousel at the runtime (KivyMD 2.0.1.dev0). More precisely, I am passing the data from one MDScreen to the other (containing the MDTabsPrimary) at the on_press() of a button. The problem is that the example uses the MDApp.on_start() method for doing these, whereas I am trying to do the same inside the MDScreen.on_enter(). This causes the following error:

    Traceback (most recent call last):
    File "C:\Users\sapta\miniconda3\envs\android\lib\site-packages\kivy\app.py", line 956, in run
    runTouchApp()
    File "C:\Users\sapta\miniconda3\envs\android\lib\site-packages\kivy\base.py", line 574, in runTouchApp
    EventLoop.mainloop()
    File "C:\Users\sapta\miniconda3\envs\android\lib\site-packages\kivy\base.py", line 339, in mainloop
    self.idle()
    File "C:\Users\sapta\miniconda3\envs\android\lib\site-packages\kivy\base.py", line 379, in idle
    Clock.tick()
    File "C:\Users\sapta\miniconda3\envs\android\lib\site-packages\kivy\clock.py", line 733, in tick
    self.post_idle(ts, self.idle())
    File "C:\Users\sapta\miniconda3\envs\android\lib\site-packages\kivy\clock.py", line 776, in post_idle
    self._process_events()
    File "kivy\\_clock.pyx", line 620, in kivy._clock.CyClockBase._process_events
    File "kivy\\_clock.pyx", line 653, in kivy._clock.CyClockBase._process_events
    File "kivy\\_clock.pyx", line 649, in kivy._clock.CyClockBase._process_events
    File "kivy\\_clock.pyx", line 218, in kivy._clock.ClockEvent.tick
    File "C:\Users\sapta\miniconda3\envs\android\lib\site-packages\kivymd\uix\tab\tab.py", line 1234, in <lambda>
    lambda x: self._tabs_carousel.current_slide.tab_item.dispatch(
    AttributeError: 'NoneType' object has no attribute 'tab_item'


    Minimal (non-)working example:

    from kivy.lang import Builder
    from kivymd.app import MDApp
    from kivymd.uix.list import (
    MDListItem, MDListItemHeadlineText, MDListItemLeadingIcon
    )
    from kivymd.uix.screen import MDScreen
    from kivymd.uix.screenmanager import MDScreenManager
    from kivymd.uix.tab import MDTabsItem, MDTabsItemIcon, MDTabsItemText


    KV = '''
    <MyScreen1>:
    MDButton:
    style: "elevated"
    pos_hint: {"center_x": .5, "center_y": .5}
    on_press: root.on_press(*args)
    MDButtonIcon:
    icon: "plus"
    MDButtonText:
    text: "Elevated"

    <MyScreen2>:
    md_bg_color: self.theme_cls.backgroundColor

    MDTabsPrimary:
    id: tabs
    pos_hint: {"center_x": .5, "center_y": .5}
    size_hint_x: 0.8
    allow_stretch: False

    MDDivider:

    MDTabsCarousel:
    id: related_content_container
    size_hint_y: None
    height: dp(320)
    '''

    class MyScreen2(MDScreen):
    def on_enter(self, *args):
    for item in self.my_data:
    self.ids.tabs.add_widget(
    MDTabsItem(
    MDTabsItemIcon(
    icon="airplane",
    ),
    MDTabsItemText(
    text=item,
    ),
    )
    )
    self.ids.related_content_container.add_widget(
    MDListItem(
    MDListItemLeadingIcon(icon="email"),
    MDListItemHeadlineText(text=item),
    )
    )


    class MyScreen1(MDScreen):
    def on_press(self, *args):
    self.manager.get_screen("screen_2").my_data = ["item_1", "item_2", "item_3"]
    self.manager.current = "screen_2"


    class Example(MDApp):
    def build(self):
    self.theme_cls.primary_palette = "Olive"
    _ = Builder.load_string(KV)

    self.sm = MDScreenManager()
    self.sm.add_widget(
    MyScreen1(
    name="screen_1",
    md_bg_color=self.theme_cls.backgroundColor,
    )
    )
    self.sm.add_widget(
    MyScreen2(
    name="screen_2",
    md_bg_color=self.theme_cls.backgroundColor,
    )
    )

    return self.sm


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

    Continue reading...

Compartilhe esta Página