Сброс настроек kivy к исходным значениям

#python #kivy #kivymd

#python #kivy #kivymd

Вопрос:

Я создаю приложение, и мне было интересно, как сбросить настройки kivy до значений по умолчанию. Кроме того, можно ли добавить кнопку, которая сбрасывает настройки до их значений по умолчанию. Вот мой код:

 from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.settings import SettingsWithSidebar
from plyer.facades.storagepath import StoragePath
import plyer, json

settings_json = json.dumps([
    {'type': 'title',
     'title': 'example title'},
    {'type': 'bool',
     'title': 'A boolean setting',
     'desc': 'Boolean description text',
     'section': 'example',
     'key': 'boolexample'},
    {'type': 'numeric',
     'title': 'A numeric setting',
     'desc': 'Numeric description text',
     'section': 'example',
     'key': 'numericexample'},
    {'type': 'options',
     'title': 'An options setting',
     'desc': 'Options description text',
     'section': 'example',
     'key': 'optionsexample',
     'options': ['option1', 'option2', 'option3']},
    {'type': 'string',
     'title': 'A string setting',
     'desc': 'String description text',
     'section': 'example',
     'key': 'stringexample'},
    {'type': 'path',
     'title': 'Download Folder Path',
     'desc': "All downloaded manga will be found in this folder called 'manga_downloader_root' ",
     'section': 'example',
     'key': 'pathexample'}])

Builder.load_string('''
<Interface>:
    orientation: 'vertical'
    Button:
        text: 'open the settings!'
        font_size: 150
        on_release: app.open_settings()
        on_press: app.destroy_settings()
''')

class Interface(BoxLayout):
    pass

class SettingsApp(App):
    def build(self):
        self.settings_cls = SettingsWithSidebar
        self.use_kivy_settings = False
        setting = self.config.get('example', 'pathexample')
        print(setting)
        print(plyer.storagepath.get_downloads_dir())
    
        return Interface()

    def build_config(self, config):
        user_downloads_dir = plyer.storagepath.get_downloads_dir()

        config.setdefaults('example', {
            'boolexample': True,
            'numericexample': 10,
            'optionsexample': 'option2',
            'stringexample': 'some_string',
            'pathexample': user_downloads_dir })

    def build_settings(self, settings):
        settings.add_json_panel('Panel Name', self.config, data=settings_json)
        
    def on_config_change(self, config, section, key, value):
        print (config, section, key, value)
if __name__ == "__main__":
   SettingsApp().run()
  

Для большего контекста я хочу, чтобы это приложение работало как на Android, так и на ПК. Можно ли также включить этот код в панель навигации, которая может быть открыта с помощью значка.

Ответ №1:

Итак, я понял это некоторое время назад, я опубликую минимальный ответ для всех, кто найдет это. Мое решение использует этот код из этого поста на Github.

 from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.settings import SettingItem, SettingsWithSpinner
import plyer, json

settings_json = json.dumps([
    {
        'type': 'title',
        'title': 'example title'
    },

    {
        'type': 'bool',
        'title': 'A boolean setting',
        'desc': 'Boolean description text',
        'section': 'example',
        'key': 'boolexample'
    },

    {
        'type': 'numeric',
        'title': 'A numeric setting',
        'desc': 'Numeric description text',
        'section': 'example',
        'key': 'numericexample'
     },

    {
        'type': 'options',
        'title': 'An options setting',
        'desc': 'Options description text',
        'section': 'example',
        'key': 'optionsexample',
        'options': ['option1', 'option2', 'option3'] 
    },

    {
        'type': 'string',
        'title': 'A string setting',
        'desc': 'String description text',
        'section': 'example',
        'key': 'stringexample'
    },

    {
        'type': 'path',
        'title': 'Download Folder Path',
        'desc': "All downloaded manga will be found in this folder called 'manga_downloader_root' ",
        'section': 'example',
        'key': 'pathexample'
    },

    # Added a button to reset the settings
    {
       "type":"buttons",
       "title":"Reset Settings",
       "desc":"Reset the settings to their default values",
       "section":"Settings",
       "key":"configchangebuttons",
       "buttons":[{"title":"Reset Settings", "id":"reset_settings_btn"}]
    }
         
])

class Interface(BoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.add_widget(Button(text="Open Settings", on_release=App.get_running_app().open_settings))

# Class to create a button-type settings item
class SettingButtons(SettingItem):
    def __init__(self, **kwargs):
        # For Python3 compatibility we need to drop the buttons keyword when calling super.
        kw = kwargs.copy()
        kw.pop('buttons', None)
        super(SettingItem, self).__init__(**kw)
        
        for aButton in kwargs["buttons"]:
            oButton=Button(text=aButton['title'], font_size= '15sp', on_release=self.on_button_press)
            oButton.ID=aButton['id']
            self.add_widget(oButton)
    
    def set_value(self, section, key, value):
        # set_value normally reads the configparser values and runs on an error (to do nothing here)
        return
    
    def on_button_press(self,instance):
        self.panel.settings.dispatch('on_config_change',self.panel.config, self.section, self.key, instance.ID)


class ScrollableSettings(SettingsWithSpinner):
    def __init__(self, *args, **kwargs):
        super().__init__(*args,**kwargs)
        self.settings_types = [('buttons', SettingButtons)] # 'buttons' is the name of the settings type

        # Registers any new settings types
        for type_ in self.settings_types:
            self.register_type(*type_)


class SettingsApp(App):
    default_settings = {
            'boolexample': True,
            'numericexample': 10,
            'optionsexample': 'option2',
            'stringexample': 'some_string',
            'pathexample': plyer.storagepath.get_downloads_dir() 
    }
    
    def build(self):
        self.settings_cls = ScrollableSettings
        self.use_kivy_settings = False
        #setting = self.config.get('example', 'pathexample')
    
        return Interface()

    def build_config(self, config):
        config.setdefaults('example', self.default_settings)

    def build_settings(self, settings):
        settings.add_json_panel('Panel Name', self.config, data=settings_json)
        
    def on_config_change(self, config, section, key, value):
        print (config, section, key, value)

        if key == "configchangebuttons":
            # Reset config to defaults and write new vals 
            config.setall('example', self.default_settings)
            config.write()
            # Refreshes the settings menu to show that the default settings have been applied
            self.close_settings()
            self.destroy_settings()
            self.open_settings()

if __name__ == "__main__":
   SettingsApp().run()