Psionman
Psionman

Reputation: 3677

How can I get kivy app to open a dropdown

I am trying to get a kivy app to open a dropdown. I am following the example here.

When I run the app I can click on the button, but no dropdown appears.

I am missing something simple, but I just can't see it. Can someone help please.

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import Screen
from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button
from kivy.lang import Builder

root = Builder.load_string('''
<MainFrame>:
    BoxLayout:
        orientation: 'vertical'
        Label:
            text: 'Hello'
        Button:
            text: 'open dropdown'
            on_press: root.on_menu_button_click()
''')

class MainFrame(Screen):
    def __init__(self, **kwargs):
        super(MainFrame, self).__init__(**kwargs)
        self.dropdown = self._create_dropdown()

    def _create_dropdown(self):
        dropdown = DropDown()
        for index in range(5):
            btn = Button(text='Value %d' % index, size_hint_y=None, height=44)
            btn.bind(on_release=lambda btn: dropdown.select(btn.text))
            dropdown.add_widget(btn)
        return dropdown

    def on_menu_button_click(self):
        self.dropdown.open

class BasicApp(App):
    def build(self):
        return MainFrame()

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

Upvotes: 1

Views: 48

Answers (1)

eyllanesc
eyllanesc

Reputation: 243993

You have to use the open() method and pass the button, you must also use on_release instead of on_press.

from kivy.app import App
from kivy.uix.screenmanager import Screen
from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button
from kivy.lang import Builder

root = Builder.load_string('''
<MainFrame>:
    BoxLayout:
        orientation: 'vertical'
        Label:
            text: 'Hello'
        Button:
            id: btn  # <---
            text: 'open dropdown'
            on_release: root.on_menu_button_click(btn) # <---
''')

class MainFrame(Screen):
    def __init__(self, **kwargs):
        super(MainFrame, self).__init__(**kwargs)
        self.dropdown = self._create_dropdown()

    def _create_dropdown(self):
        dropdown = DropDown()
        for index in range(5):
            btn = Button(text='Value %d' % index, size_hint_y=None, height=44)
            btn.bind(on_release=lambda btn: dropdown.select(btn.text))
            dropdown.add_widget(btn)
        return dropdown

    def on_menu_button_click(self, widget): # <---
        self.dropdown.open(widget) # <---

class BasicApp(App):
    def build(self):
        return MainFrame()

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

The above is clearly mentioned in the example as it indicates:

...
# show the dropdown menu when the main button is released
# note: all the bind() calls pass the instance of the caller (here, the
# mainbutton instance) as the first argument of the callback (here,
# dropdown.open.).
mainbutton.bind(on_release=dropdown.open)
...

Upvotes: 1

Related Questions