Search code examples
pythonoopkivykivy-languageconfigparser

ConfigParserProperty returning val inside class kivy


I am following the official kivy documentation, and I ran into an issue, here is my code, at the bottom I will explain what's wrong.

KV = '''
BoxLayout:
    TextInput:
        id: number
        text: str(app.number)
        on_text: app.number = self.text
    Label:
        id: info
        number: number.text
        text: 'Number: {}'.format(self.number)
''' 


class InfoApp(App):

    def build_config(self, config):
        config.setdefaults(
            'info',
            {
                'number': ''
            }
        )
    number = ConfigParserProperty(0, 'info', 'number', 'app',val_type=int)

    def build(self):
        print(self.number)
        return Builder.load_string(KV)


if __name__ == '__main__':
    InfoApp().run()

The program works, but in the build function I print self.number, that returns 0 instead of the number stored in the config file, how can I fix that, so if I add more widgets of calculations inside build function it will properly know the number?

Any help will be appreciated! Thanks!


Solution

  • ConfigParserProperty setup things to happen after the build, so sadly you can't rely on the value from config being available in build or even on_start it's updated as soon as possible after that, but it doesn't happen before.

    So you have two choices, either also delaying your operation by a fixed amount of time (using Clock.schedule_once) and to in the called function whatever you wanted to do with the value, or (better) bind a function to the property you are interested in, so it's called every time the value changes, which is likely what you want anyway, since you'll want to refresh the interface depending on this value.

    KV = '''
    BoxLayout:
        TextInput:
            id: number
            text: str(app.number)
            on_text: app.number = self.text
        Label:
            id: info
            number: number.text
            text: 'Number: {}'.format(self.number)
    ''' 
    
    
    class InfoApp(App):
    
        def build_config(self, config):
            config.setdefaults(
                'info',
                {
                    'number': ''
                }
            )
        number = ConfigParserProperty(0, 'info', 'number', 'app',val_type=int)
    
        def build(self):
            self.bind(number=self.do_something)
            return Builder.load_string(KV)
    
        def do_something(self, *args):
            print(self.number)
    
    
    if __name__ == '__main__':
        InfoApp().run()