Search code examples
pythonkivykivy-languagekivymd

Adding widgets to the list Kivy and KivyMD


I am trying to create an application, but I ran into a problem. I need to add items to the list using a for loop, but whenever I try to do this, I get an error message. I will also be glad to hear tips for improving the code.

self.root.ids.List_setting.add_widget(
File "kivy\properties.pyx", line 964, in kivy.properties.ObservableDict.__getattr__
AttributeError: 'super' object has no attribute '__getattr__'

Main.py:

from kivymd.app import MDApp
from kivy.base import Builder
from kivy.uix.widget import Widget
from kivy.core.window import Window
# Layout
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.gridlayout import MDGridLayout
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.recycleview import RecycleView
from kivymd.uix.floatlayout import MDFloatLayout
#Widget KivyMD
from kivymd.uix.toolbar import MDToolbar
from kivymd.uix.imagelist import SmartTileWithLabel
from kivymd.uix.chip import MDChooseChip
from kivymd.uix.chip import MDChip
from kivymd.uix.textfield import MDTextField
from kivymd.uix.list import OneLineListItem
from kivymd.icon_definitions import md_icons
from kivymd.uix.screen import MDScreen
from kivymd.uix.label import MDLabel
from kivymd.uix.textfield import MDTextFieldRound
from kivymd.uix.bottomnavigation import MDBottomNavigation
from kivymd.uix.bottomnavigation import MDBottomNavigationBar
#widget Kivy
from kivy.uix.screenmanager import Screen
from kivy.uix.screenmanager import ScreenManager
from kivy.uix.scrollview import ScrollView
from kivy.clock import Clock
from kivy.uix.button import Button


class first_main_screen(Screen):
        Screen.name = 'Main'

class First_main_screen(Widget):
    pass

class main_activity(MDApp):
    Window.size = (400, 680)
    def build(self):
        global sm
        self.theme_cls.primary_palette = "Purple"  # "Purple", "Red"
        self.theme_cls.primary_hue = "500"  # "500"
        sm = ScreenManager()
        sm.add_widget(Builder.load_file('screen_py/kv_screen/splash_screen.kv'))
        sm.add_widget(Builder.load_file('kv_main/kv_main.kv'))
        return sm

    def on_start(self):
        Clock.schedule_once(self.kv_main,5)
        self.fps_monitor_start()


    def kv_main(self, *args):
        sm.current = 'Main'
        self.root.ids.List_setting.add_widget(
            OneLineListItem(text=f'Items_13')
        )


if __name__=='__main__':
    main_activity().run()

kv_main.kv:

#:import images_path kivymd.images_path
first_main_screen:
    name:'Main'
    MDBoxLayout:
        orientation:'vertical'
        size_hint:(None, None)
        height: root.height
        width: root.width
        MDBottomNavigation:
            panel_color: rgba(151, 172, 177)
            MDBottomNavigationItem:
                panel_color: (151/255, 172/255, 177/255, 1/255)
                specific_text_color: 1, 1, 1, 1
                text:'Главная'
                icon:'home'
                name: 'screen 1'
                RecycleView:
                    size_hint:(None, None)
                    height: root.height-57
                    width: root.width
                    MDGridLayout:
                        cols: 2
                        id:image_list
                        row_default_height: (self.width - self.cols*self.spacing[0]) / self.cols
                        row_force_default: True
                        size_hint_y: None
                        height: self.minimum_height
                        spacing: dp(3)
                        SmartTileWithLabel:
                            text:'[size=26]Items 1 [/size]\n[size=14]Купить[/size]'
                            source:'image_main_kv/img.png'
                            height:('400dp')
                        SmartTileWithLabel:
                            text:'[size=26]Items 1 [/size]\n[size=14]Купить[/size]'
                            source:'image_main_kv/img.png'
                            height:('400dp')
                        SmartTileWithLabel:
                            text:'[size=26]Items 1 [/size]\n[size=14]Купить[/size]'
                            source:'image_main_kv/img.png'
                            height:('400dp')
            MDBottomNavigationItem:
                panel_color: (151/255, 172/255, 177/255, 1/255)
                specific_text_color: 1, 1, 1,
                icon:'card-search'
                text:'Поиск'
                name: 'screen 2'
                MDBoxLayout:
                    orientation:'vertical'
                    pos_hint:{'top':1}
                    MDTextField:
                        text:'12312'
                    AnchorLayout:
                        anchor_x:'center'
                        anchor_y:'top'
                        MDChooseChip:
                            MDChip:
                                text: 'Check with icon'
                                icon: 'city'
                                check: True
            MDBottomNavigationItem:
                panel_color: (151/255, 172/255, 177/255, 1/255)
                specific_text_color: 1, 1, 1, 1
                text:'Настройки'
                icon:'account-settings'
                name: 'screen 3'
                RecycleView:
                    MDList:
                        id:List_setting
                        OneLineListItem:
                            text:'1231231'

please explain how to fix this error or make the code effective.


Solution

  • You are getting that error because of the code:

        self.root.ids.List_setting.add_widget(
            OneLineListItem(text=f'Items_13')
        )
    

    This code is trying to access the ids of the root widget of the App, but the App widget root is the ScreenManager, which has no ids defined. The ids in your kv file are defined in the first_main_screen widget. So, I think all you have to do is access the ids of the first_main_screen, like this:

        self.root.get_screen('Main').ids.List_setting.add_widget(
            OneLineListItem(text=f'Items_13')
        )
    

    This uses the get_screen() method of the ScreenManager, that is the root of the App, to access the first_main_screen and then its ids.