Reputation: 315
Kivy has this awesome built-in functionality for creating a settings panel for your app. It gives you a set of entry types you can use like string, bool, options, etc. But all of these options are hard coded in json files, and if there something dynamic going on, what do you do?
How can you have a dynamically changing settings menu in Kivy?
Specifically, I need to have a settings panel for serial connectivity. My app's user would need to choose to which existing serial ports he wants to connect. This list can be obtained in python, but it can change at any time, so how can I keep my settings menu up to date with the current com ports availability?
Upvotes: 1
Views: 1169
Reputation: 315
There are probably several ways of doing it. Here's one of them:
Create a new type of setting, that accepts a function as a string, that will contain a full path to the function you want to call each time the user wants to look at the list:
class SettingDynamicOptions(SettingOptions):
'''Implementation of an option list that creates the items in the possible
options list by calling an external method, that should be defined in
the settings class.
'''
function_string = StringProperty()
'''The function's name to call each time the list should be updated.
It should return a list of strings, to be used for the options.
'''
def _create_popup(self, instance):
# Update the options
mod_name, func_name = self.function_string.rsplit('.',1)
mod = importlib.import_module(mod_name)
func = getattr(mod, func_name)
self.options = func()
# Call the parent __init__
super(SettingDynamicOptions, self)._create_popup(instance)
It's subclassed from SettingOptions, which lets the user choose from a drop-down list. Each time the user presses the setting to see the possible options, the _create_popup
method is called. The new overriden method dynamically imports the function and calls it to update the class's options attribute (which is reflected in the drop-down list).
Now it's possible to create such a settings item in json:
{
"type": "dynamic_options",
"title": "options that are always up to date",
"desc": "some desc.",
"section": "comm",
"key": "my_dynamic_options",
"function_string": "my_module.my_sub_module.my_function"
},
It's also necessary to register the new settings type by subclassing Kivy's settings class:
class MySettings(SettingsWithSidebar):
'''Customized settings panel.
'''
def __init__(self, *args, **kargs):
super(MySettings, self).__init__(*args, **kargs)
self.register_type('dynamic_options', SettingDynamicOptions)
and to use it for your app:
def build(self):
'''Build the screen.
'''
self.settings_cls = MySettings
Upvotes: 4