n4321d
n4321d

Reputation: 1205

Update Kivy settings panel values with changed Config

Question:

I am building an App and using the kivy settingspanel to change settings. Some of the settings are stored in ConfigParserProperties and can also be changed outside of the settings panel. When I reopen the settings panel the values in the settings panel are still the old ones.
How can I update the settings panel with the most recent values (in the ConfigParserProperties)?

What I have Tried:

Example:

This example generates a random value for variable test, which is the only item in the settings panel (open it by clicking the button or pressing f1). As you can see the value will not change from the start value.

from kivy.app import App
from kivy.properties import ConfigParserProperty
from random import randint
from kivy.clock import Clock
from kivy.uix.button import Button
import json


class MyApp(App):
    test = ConfigParserProperty(0, 'testing', 'test_par', 'app_config', val_type=int)
    use_kivy_settings = False   # disable kivy settings in options

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        Clock.schedule_interval(self.new_number, 1)

    def build(self):        
        self.config.read("test.ini")
        self.config.name = "app_config"
        _app = super().build()
        _app.add_widget(Button(text='open settings', 
                               size=_app.size, 
                               pos=_app.pos, 
                               on_release=self.open_settings))
        return _app

    def build_settings(self, settings):
        _setts = json.dumps([
        {
            "type": "title",
            "title": "Test Settings"
        },
        {
            "type": "numeric",
            "title": "Test Var",
            "desc": "Randomly changing test var, wish it would change here too",
            "section": "testing",
            "key": "test_par"
        }])
        settings.add_json_panel('Test Panel', self.config, data=_setts)
        self.settings = settings

    def new_number(self, *args, **kwargs):
        # generate random new values for test
        self.test = randint(0, 0xff)
        print(self.test)

if __name__ == "__main__":
    app = MyApp()
    app.run()

What I tried:
Adding this code will change the value every time the panel is opened. But also destroys and recreates the panel everytime you open it. Which is slow with multiple panel items.

    def open_settings(self, *args):
        self.destroy_settings()  # clear settings
        return super().open_settings(*args)

If anyone knows a way to change/update specific panel items with changes in the ConfigParserProperties, much appreciated.

Upvotes: 1

Views: 1479

Answers (2)

Kirk Jackson
Kirk Jackson

Reputation: 9

I tried this but it did not work because self.settings_cls.interface recognized but not self.settings_cls.interface.content.panels. No content or panels for Python Object settings.

Upvotes: 0

Helpy
Helpy

Reputation: 26

Had the same problem. My solution was to manually update the value of each SettingItem after changing the ConfigParser object. For this you can simply iterate over the panels of your settings widget:

from kivy.uix.settings import SettingItem

# ...

settings = <my setting widget instance>
panels = settings.interface.content.panels
    
for panel in panels.values():        
    children = panel.children

    for child in children:
        if isinstance(child, SettingItem):                    
            child.value = panel.get_value(child.section, child.key)

# ...

Maybe you have to adjust the path to the panels (.interface.content.panels), depending of the type of settings widget you use (I used default SettingsWithSidebar). The panel.get_value method gets the actual value directly out of the initially assigned ConfigParser instance.

Upvotes: 1

Related Questions