Search code examples
pythonpython-2.7kivykivy-language

how do i disable a widget based on the value of another widget in Kivy


I have a Spinner widget in a .kv file and I need the value of this Spinner to enable another Spinner widget.

This is the code i have tried and it does not work and gives me a Syntax error:

CustLabel:
    text: "Aux LO Pump Status"


CustSpinner:
    id: auxlo
    text: "Select"
    values: ('On', 'Off')
    focus: True
    on_state: (self.auxlonum.disabled) if (self.auxlo == 'off')

CustLabel:
    text: "Aux LO Pump Number"

CustSpinner:
    id: auxlonum
    text: "Select"
    values: ('# 1', '# 2')
    focus: True

i would actually prefer the auxlonum widget to start off disabled and 'greyed out' and then only be enabled if the auxlo widget had 'on' selected, however i was not sure how to go about this.

Thank you.


Solution

  • First, you can´t use on_state event because it emit before you selected one value. You need use on_text event instead.

    On the other hand, self.auxlonum is an incorrect syntax, you should use the id only to refer to any widget inside kv.

    Finally, you only need to use the ternary operator syntax to do what you want:

    Spinner:
        id: auxlo
        on_text: auxlonum.disabled = True if auxlo.text == 'Off' else False
    

    Or:

    Spinner:
        id: auxlonum
        disabled: True if auxlo.text == 'Off' else False
    

    Executable example:

    from kivy.app import App
    from kivy.uix.boxlayout import BoxLayout
    
    from kivy.lang import Builder
    
    
    Builder.load_string('''
    <MyWidget>
        orientation: 'vertical'
        Spinner:
            id: auxlo
            text: "Select"
            values: ('On', 'Off')
            focus: True
            on_text: auxlonum.disabled = True if auxlo.text == 'Off' else False
    
        Label:
    
        Spinner:
            id: auxlonum
            text: "Select"
            values: ('# 1', '# 2')
            focus: True
    
        Label:
    ''')
    
    
    class MyWidget(BoxLayout):
        pass
    
    class TestApp(App):
        def build(self):            
            return  MyWidget()
    
    TestApp().run()
    

    enter image description here