Reputation: 107
I'm using kivy to create a small App for computer aided learning.
At the moment I have some problems with accessing config values. I get the value with
self.language = self.config.get('basicsettings', 'language')
in the main App-Class. That works fine, however, I don't know how to access these value inside another widget - in this case the AudioButton.
I'm using a ScreenManager, which contains a Screen. Inside is a BoxLayout, which contains a GridLayout and this holds several AudioButtons.
Now, in this AudioButton I want to know the current value of self.language
defined in the mainApp.
In .kv files I can do something like
`text: app.language`
to get it, but how to do it directly in Python?
If I use a dummy label in kv to get the value, it works, but when I change the setting, I need to restart the App, because I don't know what I need to add to on_config_change()
to update the value during runtime.
Here's a very simplified version of my App with all interesting parts, I hope.
class AudioButton(Button):
filename = StringProperty(None)
sound = ObjectProperty(None, allownone=True)
def on_press(self):
if self.ids.playsound.text == '1':
self.sound.play()
else:
print('NoSound')
class MainScreen(Screen):
pass
class Pictures1(GridLayout):
def __init__(self, **kwargs):
super(Pictures1, self).__init__(**kwargs)
self.cols = 2
btn = AudioButton()
self.add_widget(btn)
btn = AudioButton()
self.add_widget(btn)
class Lesson1(Screen):
pass
class ScreenManagement(ScreenManager):
pass
class LunahutsoApp(App):
def build(self):
self.settings_cls = SettingsWithSidebar
self.use_kivy_settings = False
self.language = self.config.get('basicsettings', 'language')
self.playsound = self.config.get('basicsettings', 'playsound')
return ScreenManagement()
def build_config(self, config):
config.setdefaults('basicsettings', {
'language': 'austrian',
'playsound': 1})
def build_settings(self, settings):
settings.add_json_panel('Lunahutso',
self.config,
data=settings_json)
def on_config_change(self, config, section,
key, value):
if key == 'language':
self.language = value
if key == 'playsound':
self.playsound = value
if __name__ == "__main__":
LunahutsoApp().run()
And the .kv file:
<ScreenManagement>:
MainScreen:
Lesson1:
<AudioButton>:
Label:
id: language
text: app.language
color: 0, 0, 0, 0
Label:
id: playsound
text: app.playsound
color: 0, 0, 0, 0
<MainScreen>:
name: "main"
BoxLayout:
orientation: 'vertical'
Button:
on_release: app.root.current = "lesson1"
text: "Lesson"
font_size: 50
Button:
on_release: app.open_settings()
text: "Settings"
font_size: 50
Button:
on_release: sys.exit()
text: "Quit"
font_size: 50
<Lesson1>:
name: "lesson1"
id: lesson1
BoxLayout:
orientation: 'vertical'
Pictures1:
size_hint_y: 0.5
BoxLayout:
size_hint_y: 0.15
Label:
text: ""
Upvotes: 7
Views: 3556
Reputation: 8213
An alternative to App.get_running_app().config
is to use ConfigParser.get_configparser('app')
.
This gets you your config object directly.
An even better method, if you want to bind to the values or do more than just look them up once, is to use ConfigParserProperty
.
This let's you use values from your config directly as properties without having to deal with the config yourself or monitor config changes:
class LunahutsoApp(App):
language = ConfigParserProperty('austrian',
'basicsettings', 'language', 'app')
playsound = ConfigParserProperty(1,
'basicsettings', 'playsound', 'app')
...
Then you can bind the values in Kv (NOTE: the way you defined langauge
and playsound
, your Kv labels will not auto update, as they are not Properties):
<AudioButton>:
Label:
id: language
text: app.language
color: 0, 0, 0, 0
Label:
id: playsound
text: app.playsound
color: 0, 0, 0, 0
You can also define a ConfigParserProperty
on any Screen or Widget (not just the App):
class AudioButton(Button):
filename = StringProperty(None)
sound = ObjectProperty(None, allownone=True)
playsound = ConfigParserProperty('1',
'basicsettings', 'playsound', 'app')
<AudioButton>:
Label:
id: language
text: app.language
color: 0, 0, 0, 0
Label:
text: self.playsound
color: 0, 0, 0, 0
on_press: if self.playsound == '1': self.sound.play()
Upvotes: 4
Reputation: 3048
You can use the following method of the app class get_running_app()
, see here https://kivy.org/docs/api-kivy.app.html#kivy.app.App.get_running_app
This way you can reference the config from another class through the app class.
I wrote a quick example below. I am using self.text = App.get_running_app().config.get('Label','content')
to access sth in the config.
from kivy.app import App
from kivy.uix.textinput import TextInput
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.config import Config
class Labelwithconfig(Label):
def check_label(self):
self.text = App.get_running_app().config.get('Label','content')
kv_str = Builder.load_string("""
BoxLayout:
orientation: 'vertical'
Labelwithconfig:
id: labelconf
Button:
text: 'open settings'
on_press: app.open_settings()
""")
class MyApp(App):
def build_config(self, config):
config.setdefaults('Label', {'Content': "Default label text"})
def build_settings(self, settings):
settings.add_json_panel("StackOverflow Test Settings", self.config, data="""
[
{"type": "options",
"title": "Label text System",
"section": "Label",
"key": "Content",
"options": ["Default label text", "Other Label text"]
}
]"""
)
def on_config_change(self, config, section, key, value):
self.root.ids.labelconf.check_label()
def build(self):
return kv_str
if __name__ == '__main__':
MyApp().run()
Upvotes: 5