Search code examples
pythonwidgetkivydropdown

Why (Kivy) Dropdown does not show?


I am trying to create an easy example of using Kivy DropDown class. It is simple, click on a main button then the drop down list of 2 buttons should appear. I am not used with .bind method, so this is my code:

import kivy
from kivy.app import App
from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout

dropdown = DropDown()

btn1 = Button(text = "attack")
btn2 = Button(text = "item")

dropdown.add_widget(btn1)
dropdown.add_widget(btn2)


class MainButton(Button):

    def on_release(self):
        super().on_release()
        print("something")
        dropdown.open(self)


class Layout(FloatLayout):
    pass


btn = MainButton(text = "Hello")


class theApp(App):

    def build(self):
        layout = Layout()
        layout.add_widget(btn)
        btn.pos_hint = {'x': 0.5, 'y': 0.5}
        btn.size_hint = (0.25, 0.25)
        return layout


app = theApp()
app.run()

Another issue, when I use the DropDown.open method outside a class method, I get en error:

import kivy
from kivy.app import App
from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout

dropdown = DropDown()

btn1 = Button(text = "attack")
btn2 = Button(text = "item")

dropdown.add_widget(btn1)
dropdown.add_widget(btn2)

btn = Button(text = "Hello")


class theApp(App):

    def build(self):
        layout = FloatLayout()
        layout.add_widget(btn)
        btn.pos_hint = {'x': 0.5, 'y': 0.5}
        btn.size_hint = (0.25, 0.25)

        dropdown.open(btn)
        return layout


app = theApp()
app.run()

File "/usr/lib/python3/dist-packages/kivy/uix/dropdown.py", line 245, in open
     'Cannot open a dropdown list on a hidden widget')
 kivy.uix.dropdown.DropDownException: Cannot open a dropdown list on a hidden widget

Why is this? thank you.


Solution

  • The reason why you can't see the two buttons when you pressed the MainButton button was that you haven't set the height for each button.

    Try giving them a height:

    btn1 = Button(text = "attack")
    btn1.size_hint_y = None
    btn1.height = 44
    
    btn2 = Button(text = "item")
    btn2.size_hint_y = None
    btn2.height = 44
    
    dropdown.add_widget(btn1)
    dropdown.add_widget(btn2)
    

    Here's the output on my phone:

    Before clicking the button: enter image description here

    After clicking the button: enter image description here

    For your second question, I think you can't do that inside the build method since the layout widget hasn't been returned yet. You can just create a new method and execute it whenever you press the button.

    def build(self):
        layout = FloatLayout()
        layout.add_widget(btn)
        btn.pos_hint = {'x': 0.5, 'y': 0.5}
        btn.size_hint = (0.25, 0.25)
        btn.on_release = self.showDropdown
        return layout
    
    def showDropdown(self):
        dropdown.open(btn)