3
votes

I´m looking for a way to set the values of a Kivy Spinner depending on the text chosen from the parent spinner. The problem is that I have defined both spinners in kv language. I´m not sure if the approach would be to destroy the second spinner each time a new value is chosen from the first one, then regenerate it (if so I have no idea how to do that because of the kv code), or if there would be a way to dynamically update the "values" of the second spinner based on an on_text procedure updating the list.

In all cases the below code does not work. Any help appreciated. Thanks.

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout 
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.spinner import Spinner

Builder.load_string('''
<MainScreen>:
    AnchorLayout:
        anchor_x: 'center'
        anchor_y: 'top'
        BoxLayout:
            size_hint: 1, .9
            orientation: 'vertical'
            padding: 80
            spacing: 20
            Spinner:
                id: spinner_1
                text: '< Select >'
                values: root.pickType
                on_text: root.updateSubSpinner(spinner_1.text)
            Spinner:
                id: spinner_2
                text: '< Select >'
                values: root.pickSubType

    AnchorLayout:
        anchor_x: 'center'
        anchor_y: 'bottom'
        size_hint: 1, .1
        Button:
            on_press: root.onExit()
            text: 'Exit'
            font_size: 50

''')

class MainScreen(FloatLayout):
    def __init__(self, **kwargs):
        self.buildLists()
        super(MainScreen, self).__init__(**kwargs)

    def buildLists(self):
        self.pickType = ['Select','#1','#2','#3']
        self.pickSubType = ['Select'] 

    def updateSubSpinner(self,text):
        if text == '#1':
            self.pickSubType.extend('A'+'B')
        elif text == '#2':
            self.pickSubType.extend('P'+'Q')
        else:
            self.pickSubType.extend('Y'+'Z')

    def onExit(self):
        App.get_running_app().stop()

class TestApp(App):
    def build(self):
        return MainScreen()

if __name__ == "__main__": 
    TestApp().run() 
1

1 Answers

3
votes

You should reference the child spinner values list, not the pickSubType list, which isn't even bound to it. Example:

def updateSubSpinner(self, text):
    self.ids.spinner_2.text = 'Select'

    if text == '#1':
        self.ids.spinner_2.values = ['A', 'B']
    elif text == '#2':
        self.ids.spinner_2.values = ['P', 'Q']
    else:
        self.ids.spinner_2.values = ['Y', 'Z']

Writing values: root.pickSubType doesn't bind the pickSubType to the values, if the first isn't a ListProperty. You could upgrade it to a ListProperty if you like, but it is not necessary.