Home > Back-end >  Creating DropDown List in Kivy using for loop in .kv file
Creating DropDown List in Kivy using for loop in .kv file

Time:10-26

I am coding a system in kivy that requires the user to input a 3 letter abbreviation of a sports team's name. E.G 'ENG' for England like you would see on a scoreboard. I am trying to use dropdown menus to do this, and am writing these dropdowns in my .kv file. However, at the moment I am having to write them by defining each button in the dropdown individually - 26 different buttons, 3 times over. I know that I can use for loops in kv lang to alter labels or return values, but I cannot find a way to use them to add buttons - what I want to do. Does anyone know of an elegant way to solve my problem?

Here is the .kv code:

<NameScreen>:
    Button:
        pos_hint:{'center_x': .5, 'center_y': .5}
        id: drop_letters1_menu
        text: 'Select Letter'
        size_hint_y: None
        height: 44
        on_parent: drop_player_numbers_tens.dismiss()
        on_release: drop_player_numbers_tens.open(self)

        DropDown:
            id: drop_letters1
            on_select:
                letter_btn1.text = '{}'.format(args[1])
            max_height: 120


            Button:
                id: btn_a1
                text: 'A'
                size_hint_y: None
                height: 35
                on_release: drop_player_numbers_tens.select('1')


            Button:
                id: btn_b1
                text: 'B'
                size_hint_y: None
                height: 35
                on_release: drop_player_numbers_tens.select('self.text')

            Button:
                id: btn_c1
                text: 'C'
                size_hint_y: None
                height: 35
                on_release: drop_player_numbers_tens.select('self.text')

# This continues for all alphabet A-Z

and the .py code:

class NamingScreen(Screen):
    pass






class TheApp(App):

    alphabet_list = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
       # The above line was to try and iterate through an alphabet list for this problem, 
       # but I got stuck on the main question's issue

    def build(self):
        # Create the screen manager
        sm = ScreenManager()
        sm.add_widget(NamingScreen(name='name_screen'))

        return sm

def main():
    Builder.load_file('menu.kv')
    app = TheApp()
    app.run()

if __name__ == '__main__':
    main()

Any help would be greatly appreciated, and let me know if there is any additional information you need :)

CodePudding user response:

You can either use a default method (like on_start) or a custom method (in which case you have to call it properly) as follows:

    def build(self):
        # Create the screen manager
        sm = ScreenManager()
        sm.add_widget(NamingScreen(name='name_screen'))
        return sm


    def on_start(self):
        # First access the desired screen.
        name_screen = self.root.get_screen('name_screen')
        # Then access the target drop-down by id.
        drop_down = name_screen.ids.drop_player_numbers_tens
        # Now iterate over...
        for name in self.alphabet_list:
            btn = Button(
                text = name,
                size_hint_y = None,
                height = 35,
            )
            btn.bind(on_release = lambda btn_obj : drop_down.select(btn_obj.text))
            drop_down.add_widget(btn)

For that your modified .kv code will be like,

        ...
        DropDown:
#            id: drop_letters1 # Not consistent !
            id: drop_player_numbers_tens
            on_select:
                drop_letters1_menu.text = '{}'.format(args[1])
#                letter_btn1.text = '{}'.format(args[1])
            max_height: 120


#            Button:
#                id: btn_a1
#                text: 'A'
#                size_hint_y: None
#                height: 35
#                on_release: drop_player_numbers_tens.select('1')
            ...
  • Related