Search code examples
kivykivymd

Kivy throws this error while populating json data in kivy app using ids: 'super' object has no attribute '__


I am writing a kivy program to populate news articles from stored json to kivy app. In kivy file: HomePage has box layout with id and I am trying to populate the same with python file using ids. ids is not working. I tried printing ids dictionary and the same, is printed blank. Code is as below :

import json

from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
from kivymd.app import MDApp
from kivymd.uix.screen import MDScreen

from components.news_scroll import NewsScroll

Builder.load_file('main.kv')


class HomePage(Screen):
    def on_enter(self):
        self.list_news()

    def list_news(self):

        with open('news2023-07-15.json') as user_file:
            parsed_json = json.load(user_file)
            for result in parsed_json['results']:
                self.ids._news.add_widget(NewsScroll(
                    news_title=result['title'],
                    news_content=result['content']
                ))


class RootWidget(ScreenManager):
    pass


class MainApp(MDApp):
    def build(self):
        return RootWidget()


MainApp().run()

Kivy file is as below:

#: import NewsScroll components.news_scroll.NewsScroll
<RootWidget>:
    HomePage:

<HomePage>:
    BoxLayout:
        orientation: 'vertical'
        id: _news

I am getting this error:

 Traceback (most recent call last):
   File "kivy/properties.pyx", line 961, in kivy.properties.ObservableDict.__getattr__
 KeyError: '_news'
 
 During handling of the above exception, another exception occurred:
 
 Traceback (most recent call last):
   File "/Users/pradnyanandmanoharjadhav/PycharmProjects/pythonProject/main.py", line 37, in <module>
     MainApp().run()
   File "/Users/pradnyanandmanoharjadhav/PycharmProjects/pythonProject/venv/lib/python3.11/site-packages/kivy/app.py", line 955, in run
     self._run_prepare()
   File "/Users/pradnyanandmanoharjadhav/PycharmProjects/pythonProject/venv/lib/python3.11/site-packages/kivy/app.py", line 925, in _run_prepare
     root = self.build()
            ^^^^^^^^^^^^
   File "/Users/pradnyanandmanoharjadhav/PycharmProjects/pythonProject/main.py", line 34, in build
     return RootWidget()
            ^^^^^^^^^^^^
   File "/Users/pradnyanandmanoharjadhav/PycharmProjects/pythonProject/venv/lib/python3.11/site-packages/kivy/uix/screenmanager.py", line 973, in __init__
     super(ScreenManager, self).__init__(**kwargs)
   File "/Users/pradnyanandmanoharjadhav/PycharmProjects/pythonProject/venv/lib/python3.11/site-packages/kivy/uix/floatlayout.py", line 65, in __init__
     super(FloatLayout, self).__init__(**kwargs)
   File "/Users/pradnyanandmanoharjadhav/PycharmProjects/pythonProject/venv/lib/python3.11/site-packages/kivy/uix/layout.py", line 76, in __init__
     super(Layout, self).__init__(**kwargs)
   File "/Users/pradnyanandmanoharjadhav/PycharmProjects/pythonProject/venv/lib/python3.11/site-packages/kivy/uix/widget.py", line 366, in __init__
     self.apply_class_lang_rules(
   File "/Users/pradnyanandmanoharjadhav/PycharmProjects/pythonProject/venv/lib/python3.11/site-packages/kivy/uix/widget.py", line 470, in apply_class_lang_rules
     Builder.apply(
   File "/Users/pradnyanandmanoharjadhav/PycharmProjects/pythonProject/venv/lib/python3.11/site-packages/kivy/lang/builder.py", line 540, in apply
     self._apply_rule(
   File "/Users/pradnyanandmanoharjadhav/PycharmProjects/pythonProject/venv/lib/python3.11/site-packages/kivy/lang/builder.py", line 659, in _apply_rule
     widget.add_widget(child)
   File "/Users/pradnyanandmanoharjadhav/PycharmProjects/pythonProject/venv/lib/python3.11/site-packages/kivy/uix/screenmanager.py", line 1001, in add_widget
     self.current = widget.name
     ^^^^^^^^^^^^
   File "kivy/properties.pyx", line 520, in kivy.properties.Property.__set__
   File "kivy/properties.pyx", line 567, in kivy.properties.Property.set
   File "kivy/properties.pyx", line 606, in kivy.properties.Property._dispatch
   File "kivy/_event.pyx", line 1307, in kivy._event.EventObservers.dispatch
   File "kivy/_event.pyx", line 1213, in kivy._event.EventObservers._dispatch
   File "/Users/pradnyanandmanoharjadhav/PycharmProjects/pythonProject/venv/lib/python3.11/site-packages/kivy/uix/screenmanager.py", line 1069, in on_current
     screen.dispatch('on_enter')
   File "kivy/_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch
   File "/Users/pradnyanandmanoharjadhav/PycharmProjects/pythonProject/main.py", line 15, in on_enter
     self.list_news()
   File "/Users/pradnyanandmanoharjadhav/PycharmProjects/pythonProject/main.py", line 22, in list_news
     self.ids._news.add_widget(NewsScroll(
     ^^^^^^^^^^^^^^
   File "kivy/properties.pyx", line 964, in kivy.properties.ObservableDict.__getattr__
 AttributeError: 'super' object has no attribute '__getattr__'. Did you mean: '__setattr__'?

I tried multiple things but I failed at everything. If you have some solution, kindly assist.

I tried init function. Error stays the same.


Solution

  • The problem is that the ids of the HomePage are not yet filled in when the on_enter() method is triggered. A fix is to just delay the call to list_news() slightly, until the ids dictionary is complete. You can do this by using Clock.schedule_once() like this:

    def on_enter(self):
        # self.list_news()
        Clock.schedule_once(self.list_news)
    

    This requires a small change in the list_news() signature:

    def list_news(self, *args):
    

    This accounts for the dt argument that Clock.schedule_once() adds to the call.