Kivy: Dropdown closes immediately after openning

Created on 28 Apr 2017  路  6Comments  路  Source: kivy/kivy

Versions

  • Python: 2.7
  • OS: android
  • Kivy: master

Description

Dropdown do not work in newest. It shows up and closes without a reason. Faced this problem only on android building with buildozer's android_new toolchain

Code

from kivy.app import App
from kivy.lang import Builder


kv = '''
BoxLayout:
    orientation: 'vertical'
    BoxLayout:
        size_hint_y: None
        height: '50sp'
        Button:
            id: button
            text: 'Open dropdown'
    Widget:

    DropDown:
        id: dropdown
        on_parent: self.dismiss()

        Button:
            size_hint_y: None
            text: 'item 1'
        Button:
            size_hint_y: None
            text: 'item 2'
        Button:
            size_hint_y: None
            text: 'item 3'
'''


class MyApp(App):
    def build(self):
        self.root = Builder.load_string(kv)
        self.root.ids.button.bind(on_release=self.root.ids.dropdown.open)
        return self.root


MyApp().run()

Apk

MyApp-debug.zip

Widgets

Most helpful comment

Putting the on_parent: self.dismiss() on the Button works as intended. It will not automatically open the DropDown when the App first launches and it will not automatically close the DropwDown once it is open.

Change the call to: on_parent: dropdown.dismiss().

It's a bit "hacky" but it works well.

#:kivy 1.0

<InputFileDropDown>:

    Button:
        id: btn
        text: 'Input File'
        on_parent: dropdown.dismiss()
        on_release: dropdown.open(self)
        size_hint_y: None
        height: 35

    DropDown:
        id: dropdown
        on_select: btn.text = '{}'.format(args[1])

        Button:
            text: 'First Item'
            size_hint_y: None
            height: 35
            on_release: dropdown.select('First Item')

        Label:
            text: 'Second Item'
            size_hint_y: None
            height: 35

        Button:
            text: 'Third Item'
            size_hint_y: None
            height: 35
            on_release: dropdown.select('Third Item')

'InputFileDropDown' is a BoxLayout fyi.

All 6 comments

I think it's a bug in stable (at least that's where such code comes from) and is fixed in master. To be more specific this is what you see:

  • DropDown is added as a child (because you added it manually) -> has parent
  • on_parent event is triggered -> dismisses DropDown

everything seems fine until now, _yet_ the logic behing DropDown is that a user is supposed to _attach_ it to something(via its own behavior with Dropdown.open(<widget>)) and _not_ add it _as a child_ to some widget. Well, at least not this way when you are trying to hide it with on_parent: self.dismiss() because you incorrectly used it right in the beginning. See what happens next (pun :D )!

  • DropDown is dismissed, but you (now correctly) attach it to the widget, because <widget>.bind(<stuff>) passes an argument to the DropDown.open() method - the button's instance
  • DropDown is added as a child via it's own behavior somewhere (probably to the button, I'm not sure now) and the DropDown's on_parent is updated
  • on_parent is updated and triggers the dismissing event <- see?

So, what to do now? First of all, you should stop use on_parent this way and do either:

<MyDropDown>:  # make a class in python (or use "@DropDown" and Factory)
    text: 'blah'
# and *don't* add it as a child manually

which is making only the KV rule itself without using it as a child directly (like a class vs instance comparison) or if you want to go for the adding widget behavior, use Spinner as it's build for that purpose.

Theoretically you might be able to unbind the on_parent event although I'm not quite sure if even directly in on_parent or only from outside, but that's just an ugly way how to "make it work", so I'm not going to write it. 馃構

Thanks. I used DropDown as new class and this worked

Could you elaborate on how to use the @DropDown in the kv file?

I have kivy 1.10.1, windows 10, python 3.7 and it works for me if I don't write on_parent: self.dismiss() (which I don't know what it does)

Putting the on_parent: self.dismiss() on the Button works as intended. It will not automatically open the DropDown when the App first launches and it will not automatically close the DropwDown once it is open.

Change the call to: on_parent: dropdown.dismiss().

It's a bit "hacky" but it works well.

#:kivy 1.0

<InputFileDropDown>:

    Button:
        id: btn
        text: 'Input File'
        on_parent: dropdown.dismiss()
        on_release: dropdown.open(self)
        size_hint_y: None
        height: 35

    DropDown:
        id: dropdown
        on_select: btn.text = '{}'.format(args[1])

        Button:
            text: 'First Item'
            size_hint_y: None
            height: 35
            on_release: dropdown.select('First Item')

        Label:
            text: 'Second Item'
            size_hint_y: None
            height: 35

        Button:
            text: 'Third Item'
            size_hint_y: None
            height: 35
            on_release: dropdown.select('Third Item')

'InputFileDropDown' is a BoxLayout fyi.

@GaryBer

... the logic behing DropDown is that a user is supposed to attach it to something(via its own behavior with Dropdown.open()) and not add it as a child to some widget. ...

Was this page helpful?
0 / 5 - 0 ratings