i am very new to kivy and trying to build a multiple screen application, thus i a am using Screenmanager. The user is supposed to start at WelcomeScreen
and shall be enabled to search for items on the SearchScreen
. So far, so good. Unfortunately, i can not find the right way to access the MDLabels (name: 'searchResult') text property on the SearchScreen. Any ideas?
The Python File:
from kivymd.app import MDApp
from kivymd.uix.screenmanager import MDScreenManager
from kivymd.uix.screen import MDScreen
import requests
class WelcomeScreen(MDScreen):
pass
class SearchScreen(MDScreen):
pass
class WindowManager(MDScreenManager):
pass
class FoodApp(MDApp):
sm = WindowManager()
searchCache = []
def magnify_callback(self):
self.sm.transition.direction = "down"
self.sm.current = "searchScreen"
def search_something(self, text):
results= []
for name in self.searchCache:
if text.lower() in name.lower():
results.append(name)
# Plus: Change the text of 'searchResult' MDLabel on SearchScreen, depending on search results.
# Plus: Instantiate as many Labels as Results exist... (max. 20)
def fetch_searchindex(self):
try:
request = requests.get("https://api.sampleapis.com/beers/ale")
request = request.json()
for obj in request:
self.searchCache.append(obj["name"])
except:
pass
def build(self):
self.sm.add_widget(WelcomeScreen(name='welcomeScreen'))
self.sm.add_widget(SearchScreen(name='searchScreen'))
self.fetch_searchindex()
return self.sm
if __name__ == '__main__':
FoodApp().run()
The kivy file:
WindowManager:
WelcomeScreen:
SearchScreen:
<WelcomeScreen>:
name: 'welcomeScreen'
MDTopAppBar:
title: 'Welcome!'
right_action_items: [['magnify', lambda x: app.magnify_callback()]]
<SearchScreen>:
name: 'searchScreen'
MDLabel:
name: 'searchResult'
text: 'Lorem Ipsum Dolor'
size_hint: 0.8, None
pos_hint: {'center_x': 0.5, 'top': 0.8}
MDTextField:
name: 'searchText'
pos_hint: {'center_x': 0.5, 'top': 1}
size_hint: 0.8, None
hint_text: 'Search for...'
icon_left: 'magnify'
on_text: app.search_something(self.text)
MDIconButton:
icon: 'close'
pos_hint: {'right': 0.99, 'top': 0.99}
on_release:
root.manager.transition.direction = 'up'
root.manager.current = 'welcomeScreen'
I tried to use id
instead of name
in the .kv File and change the MDLabel.text property via self.sm.get_screen('searchScreen').ids.searchResult.text = 'New text'
in .py File, unfortunately i receive this error in any case...
[...]
File "C:\Projectpath\venv\lib\site-packages\kivy\lang\builder.py", line 55, in custom_callback
exec(__kvlang__.co_value, idmap)
File "C:\Projectpath\foodapp.kv", line 27, in <module>
on_text: app.search_something(self.text)
File "C:\Projectpath\main.py", line 33, in search_something
self.sm.get_screen('searchScreen').ids.searchResult.text = "Hello"
File "kivy\properties.pyx", line 964, in kivy.properties.ObservableDict.__getattr__
AttributeError: 'super' object has no attribute '__getattr__'. Did you mean: '__setattr__'?
self.sm.get_screen('searchScreen').ids
is a dictionary, as can be read in the documentation.
And a dictionary doesn't define a __getattr__
(attribute access) or __setattr__
(setting attributes). Dicts in python only supports item access through dictionary['my_key']
.
So the correct way of accessing the label would be:
self.sm.get_screen('searchScreen').ids['searchResult'].text = 'New text'
Also note, that the ids
dict is usually empty and only gets populated when you use ids, what isn't the case looking at your kv
file.
(And do not put your id in quotes, as they would affect the key name to be 'searchResult'
or "searchResult"
instead of just searchResult
(without the quotes))