Nick
Nick

Reputation: 675

Kivy - ColorPicker from settings panel

I have a default settings panel:

[
    { "type": "title",
      "title": "Test application" },

    {"type": "buttons",
     "title": "Title here",
     "desc": "desc here",
     "section": "some section",
     "key": "configchangebuttons",
     "buttons":[
       {"title":"Add","id":"button_add"},
       {"title":"Del","id":"button_delete"},
       {"title":"Rename","id":"button_rename"}
     ]},

    { "type": "numeric",
      "title": "My second key",
      "desc": "Description of my second key",
      "section": "section1",
      "key": "key2" }
]

I read the documentation but i don't really see a way there to actually add an action button to the panel in order to launch the color picker and get the result to save it in the ini file.

I tried registering a new object (button) for the settings panel but it's not really working out that well.

What i am aiming at is getting the rgb code for the color the user chooses and save it in the ini file from where i will read it and use it on a label.

This is the button i tried adding

class SettingButtons(SettingItem):

    def __init__(self, **kwargs):
        self.register_event_type('on_release')
        super(SettingItem, self).__init__(**kwargs)
        for aButton in kwargs["buttons"]:
            oButton=Button(text=aButton['title'], font_size= '15sp')
            oButton.ID=aButton['id']
            self.add_widget(oButton)
            oButton.bind (on_release=self.On_ButtonPressed)

    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_ButtonPressed(self,instance):
        self.panel.settings.dispatch('on_config_change',self.panel.config, self.section, self.key, instance.ID)

And I register the instance here:

def build_settings(self, settings):
    settings.register_type('buttons', SettingButtons)
    with open("settings.json", "r") as settings_json:
        settings.add_json_panel('B4A settings', self.config, data=settings_json.read())

But when i start the app i get:

TypeError: object.__init__() takes no parameters and i know this is from the register_type part of the build_settings

EDIT

After a bit more investigations, it seems this method works and the buttons are displayed in the settings panel but only if the APK is built and run from a phone. If i run the application from my linux i get the above stated error. Any way to bypass this?

Upvotes: 3

Views: 473

Answers (3)

Olaf H.
Olaf H.

Reputation: 46

Since I was missing the actual solution to get rid of the error for the action button from previous answers, I want to add my own: To make the button compatible with Python 3 we need to remove the buttons keyword from kwargs when calling super.

def __init__(self, title, buttons, **kwargs):
    self.register_event_type('on_release')
    kw = kwargs.copy()
    kw.pop('buttons', None)
    super(SettingItem, self).__init__(**kw)
    for aButton in buttons:
        oButton=Button(text=aButton['title'], font_size= '15sp')
        oButton.ID=aButton['id']
        self.add_widget(oButton)
        oButton.bind (on_release=self.On_ButtonPressed)

From there you can do whatever you want in the on_config_change(self, config, section, key, value) function in your app class. the parameter value will contain the id of the button.

Tested with kivy 1.11.0

Upvotes: 1

Nick
Nick

Reputation: 675

Considering what I said above I managed to fix my button problem the following way:

Instead of passing **kwargs to the super inside the init like this:

super(SettingItem, self).__init__(**kwargs)

What i did is, use the Python 3 way and passed the super init without any args like this:

super(SettingItem, self).__init__()

And doing it like this it still works. now we can engage the color picker directly from the settings menu from the buttons.

I will give @KeyWeeUsr the approved answer since his replies are what led me to this conclusion.

Upvotes: 1

Peter Badida
Peter Badida

Reputation: 12189

No, it's not Settings.register_type()'s fault, nor SettingItem's fault, because that's just a FloatLayout, which would mean this would crash too:

FloatLayout('blob')

and it works just fine for me on Python 3. So, if it's not in FloatLayout, SettingItem, Settings and we are going up(or down, basically from the "base" class), then it's in SettingButtons. A simple print will tell you what's wrong:

print(kwargs)

there was a change with Python 3 (I can't find the exact url for change or pep) where it forbids you to pass keyword arguments down to the object itself.

This code works until it reaches an expected error you mention in set_value():

def __init__(self, title, buttons, **kwargs):
    print(kwargs)
    self.register_event_type('on_release')
    super(SettingItem, self).__init__(**kwargs)
    for aButton in buttons:
        oButton=Button(text=aButton['title'], font_size= '15sp')
        oButton.ID=aButton['id']
        self.add_widget(oButton)
        oButton.bind (on_release=self.On_ButtonPressed)

def set_value(self, section, key, value):
    # set_value normally reads the configparser values and runs on an error
    # to do nothing here
    return

Upvotes: 1

Related Questions