Luke Olender
Luke Olender

Reputation: 606

Positioning error in MDDropdownMenu in KivyMD

I've been having an issue with the positioning of the MDDropdownMenu in KivyMD. And I think I found a small error. Here is the relevant part of code.

.PY

class MainApp(MDApp):
    [...]
    def on_start(self):
        menu_items = [{"icon": "apple", "text": f"Item #{i}"} for i in range(5)]
        self.menu = MDDropdownMenu(
            caller=self.root.ids.MD_menu_screen.ids.button, items=menu_items, width_mult=4
        )
    [...]

.KV

<MDMenuScreen>:
    MDRaisedButton:
        id: button
        pos_hint: {'center_x': .5, 'center_y': .5}
        text: 'Open menu'
        on_release:
            app.menu.open()

And it works, but the bug is in the positioning of the menu. When you start the app, and click the button, it looks like this.

But that's not the weirdest part, when I resize the window, even when I resize and then put it back to normal, it looks normal.

So, I figured it wasn't a problem with my code. It might just be a bug. Now I was hoping someone had a (temporary) fix for this. Thanks in advance!

Upvotes: 3

Views: 687

Answers (1)

Luke Olender
Luke Olender

Reputation: 606

I found a fix myself! I looked through the source code of the MDmenu and found that it had a method named check_position_caller(self, instance, width, height), and that this function is called everytime the size or position of the window changes. Because of the fact that the menu did work fine after resizing the window, I figured it was probably because that method was being called to find the position of the caller again.

So, my solution was to call this method upon pressing the button that opens the menu. This way, the menu would first make sure it finds the right position of the caller and then open it on that position right away. So, long story short:

Change this:

<MDMenuScreen>:
    MDRaisedButton:
        id: button
        pos_hint: {'center_x': .5, 'center_y': .5}
        text: 'Open menu'
        on_release:
            app.menu.open()

Into this:

<MDMenuScreen>:
    MDRaisedButton:
        id: button
        pos_hint: {'center_x': .5, 'center_y': .5}
        text: 'Open menu'
        on_release:
            # Pass three arguments because the func needs them, it doesn't actually use them
            app.menu.check_position_caller(None, None, None) 
            app.menu.open()

It seems like this bug happens only when there are multiple screens.

I also found that this is not the only widget with this problem. For example, MDBottomNavigation also has this problem and I found a similar fix.

Upvotes: 4

Related Questions