I’m working on a Kivy app with three screens: MainScreen, LoadingScreen, and ContentScreen. Here’s what I’m trying to achieve:
On the MainScreen, I have a “Create” button.
When the button is pressed, I want to display a loading screen (LoadingScreen).
After making an API call, if I receive a successful response (status code 200), I want to transition to the ContentScreen and display the retrieved data.
However, I’m encountering an error.
Traceback (most recent call last):
File "kivy\\properties.pyx", line 961, in kivy.properties.ObservableDict.__getattr__
KeyError: 'content_label'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\graha\Documents\GitHub\kviy-skylr\app.py", line 59, in <module>
SkylrApp().run()
File "C:\Users\graha\Documents\GitHub\kviy-skylr\.venv\Lib\site-packages\kivy\app.py", line 956, in run
runTouchApp()
File "C:\Users\graha\Documents\GitHub\kviy-skylr\.venv\Lib\site-packages\kivy\base.py", line 574, in runTouchApp
EventLoop.mainloop()
File "C:\Users\graha\Documents\GitHub\kviy-skylr\.venv\Lib\site-packages\kivy\base.py", line 339, in mainloop
self.idle()
File "C:\Users\graha\Documents\GitHub\kviy-skylr\.venv\Lib\site-packages\kivy\base.py", line 383, in idle
self.dispatch_input()
File "C:\Users\graha\Documents\GitHub\kviy-skylr\.venv\Lib\site-packages\kivy\base.py", line 334, in dispatch_input
post_dispatch_input(*pop(0))
File "C:\Users\graha\Documents\GitHub\kviy-skylr\.venv\Lib\site-packages\kivy\base.py", line 302, in post_dispatch_input
wid.dispatch('on_touch_up', me)
File "kivy\\_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch
File "C:\Users\graha\Documents\GitHub\kviy-skylr\.venv\Lib\site-packages\kivy\uix\behaviors\button.py", line 179, in on_touch_up
self.dispatch('on_release')
File "kivy\\_event.pyx", line 727, in kivy._event.EventDispatcher.dispatch
File "kivy\\_event.pyx", line 1307, in kivy._event.EventObservers.dispatch
File "kivy\\_event.pyx", line 1191, in kivy._event.EventObservers._dispatch
File "C:\Users\graha\Documents\GitHub\kviy-skylr\.venv\Lib\site-packages\kivy\lang\builder.py", line 60, in custom_callback
exec(__kvlang__.co_value, idmap)
File "C:\Users\graha\Documents\GitHub\kviy-skylr\mainscreen.kv", line 30, in <module>
app.load_content(content.text)
File "C:\Users\graha\Documents\GitHub\kviy-skylr\app.py", line 53, in load_content
app.root.get_screen('content_screen').ids.content_label.text = data['data']
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "kivy\\properties.pyx", line 964, in kivy.properties.ObservableDict.__getattr__
AttributeError: 'super' object has no attribute '__getattr__'. Did you mean: '__setattr__'?
Here is my KV file:"
<MainScreen>:
BoxLayout:
orientation: 'vertical'
padding: 10
spacing: 10
# Logo at the top
Image:
source: 'images/icon.png'
size_hint: (1, 1)
# recipe input field
BoxLayout:
size_hint_y: None
height: '30'
TextInput:
id: content
multiline: False
hint_text: 'What would you like to make?'
# Button to submit the form
Button:
text: 'Create'
size_hint:(None, None)
size:(86, 34)
background_color: (1.0, 0.0, 0.0, 1.0)
font_size:'16'
on_release:
app.root.current = 'loading_screen'
app.load_content(content.text)
pos_hint: {"center_x":0.5, "center_y":0.5}
<LoadingScreen>:
BoxLayout:
orientation: 'vertical'
Label:
text: 'Loading...' # Customize as needed
font_size: '20'
size_hint_y: None
height: '50'
<ContentScreen>:
ScrollView:
do_scroll_x: False
do_scroll_y: True
BoxLayout:
orientation: 'vertical'
padding: 10
spacing: 10
Label:
id: content_label
pos_hint: {"center_x": 0.5, "center_y": 0.5}
font_size: '16'
text_size: self.width, None
Button:
text: 'Back'
size_hint:(None, None)
size:(86, 34)
background_color: (1.0, 0.0, 0.0, 1.0)
font_size:'16'
on_release:
app.root.current = 'main_screen'
app.clear_input()
pos_hint: {"center_x": 0.5, "center_y": 0.5}
and my app.py:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import Image
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen
import requests
Builder.load_file('mainscreen.kv')
class LoadingScreen(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
class ContentScreen(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
class MainScreen(Screen):
pass
class SkylrApp(App):
def build(self):
sm = ScreenManager()
sm.add_widget(MainScreen(name='main_screen'))
sm.add_widget(ContentScreen(name='content_screen'))
sm.add_widget(ContentScreen(name='loading_screen'))
return sm
def clear_input(self):
# Access the input field by its ID and clear its text
self.root.ids.content.text = ''
def load_content(self, query):
url = 'http://127.0.0.1:5000/recipes/ask_mobile'
data = {
'content': query
}
headers = {
'Content-Type': 'application/json'
}
response = requests.post(url, json=data, headers=headers)
if response.status_code == 200:
data = response.json()
app = App.get_running_app()
app.root.current = 'content_screen'
app.root.get_screen('content_screen').ids.content_label.text = data['data']
else:
print('Failed to retrieve data:', response.status_code)
if __name__ == '__main__':
SkylrApp().run()
You have a typo in your build()
method. Try changing:
sm.add_widget(ContentScreen(name='loading_screen'))
to:
sm.add_widget(LoadingScreen(name='loading_screen'))