Menu

Menus display a list of choices on temporary surfaces.

https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/menu-previous.png

Usage

from kivy.lang import Builder

from kivymd.app import MDApp
from kivymd.uix.menu import MDDropdownMenu

KV = '''
Screen:

    MDRaisedButton:
        id: button
        text: "PRESS ME"
        pos_hint: {"center_x": .5, "center_y": .5}
        on_release: app.menu.open()
'''


class Test(MDApp):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.screen = Builder.load_string(KV)
        menu_items = [{"icon": "git", "text": f"Item {i}"} for i in range(5)]
        self.menu = MDDropdownMenu(
            caller=self.screen.ids.button, items=menu_items, width_mult=4
        )

    def build(self):
        return self.screen


Test().run()
https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/menu-usage.gif

Warning

Do not create the MDDropdownMenu object when you open the menu window. Because on a mobile device this one will be very slow!

Wrong

menu = MDDropdownMenu(caller=self.screen.ids.button, items=menu_items)
menu.open()
https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/menu-wrong.gif

Customization of menu item

https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/menu-right.gif

You must create a new class that inherits from the RightContent class:

class RightContentCls(RightContent):
    pass

Now in the KV rule you can create your own elements that will be displayed in the menu item on the right:

<RightContentCls>
    disabled: True

    MDIconButton:
        icon: root.icon
        user_font_size: "16sp"
        pos_hint: {"center_y": .5}

    MDLabel:
        text: root.text
        font_style: "Caption"
        size_hint_x: None
        width: self.texture_size[0]
        text_size: None, None
https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/menu-right-detail.png

Now create menu items as usual, but add the key right_content_cls whose value is the class RightContentCls that you created:

menu_items = [
    {
        "right_content_cls": RightContentCls(
            text=f"R+{i}", icon="apple-keyboard-command",
        ),
        "icon": "git",
        "text": f"Item {i}",
    }
    for i in range(5)
]
self.menu = MDDropdownMenu(
    caller=self.screen.ids.button, items=menu_items, width_mult=4
)

Full example

from kivy.lang import Builder

from kivymd.app import MDApp
from kivymd.uix.menu import MDDropdownMenu, RightContent

KV = '''
<RightContentCls>
    disabled: True

    MDIconButton:
        icon: root.icon
        user_font_size: "16sp"
        pos_hint: {"center_y": .5}

    MDLabel:
        text: root.text
        font_style: "Caption"
        size_hint_x: None
        width: self.texture_size[0]
        text_size: None, None


Screen:

    MDRaisedButton:
        id: button
        text: "PRESS ME"
        pos_hint: {"center_x": .5, "center_y": .5}
        on_release: app.menu.open()
'''


class RightContentCls(RightContent):
    pass


class Test(MDApp):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.screen = Builder.load_string(KV)
        menu_items = [
            {
                "right_content_cls": RightContentCls(
                    text=f"R+{i}", icon="apple-keyboard-command",
                ),
                "icon": "git",
                "text": f"Item {i}",
            }
            for i in range(5)
        ]
        self.menu = MDDropdownMenu(
            caller=self.screen.ids.button, items=menu_items, width_mult=4
        )

    def build(self):
        return self.screen


Test().run()

Position menu

Bottom position

See also

position

from kivy.clock import Clock
from kivy.lang import Builder

from kivymd.app import MDApp
from kivymd.uix.menu import MDDropdownMenu

KV = '''
Screen

    MDTextField:
        id: field
        pos_hint: {'center_x': .5, 'center_y': .5}
        size_hint_x: None
        width: "200dp"
        hint_text: "Password"
        on_focus: if self.focus: app.menu.open()
'''


class Test(MDApp):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.screen = Builder.load_string(KV)
        menu_items = [{"icon": "git", "text": f"Item {i}"} for i in range(5)]
        self.menu = MDDropdownMenu(
            caller=self.screen.ids.field,
            items=menu_items,
            position="bottom",
            callback=self.set_item,
            width_mult=4,
        )

    def set_item(self, instance):
        def set_item(interval):
            self.screen.ids.field.text = instance.text

        Clock.schedule_once(set_item, 0.5)

    def build(self):
        return self.screen


Test().run()
https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/menu-position.gif

Center position

from kivy.lang import Builder

from kivymd.app import MDApp
from kivymd.uix.menu import MDDropdownMenu

KV = '''
Screen

    MDDropDownItem:
        id: drop_item
        pos_hint: {'center_x': .5, 'center_y': .5}
        text: 'Item 0'
        on_release: app.menu.open()
'''


class Test(MDApp):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.screen = Builder.load_string(KV)
        menu_items = [{"icon": "git", "text": f"Item {i}"} for i in range(5)]
        self.menu = MDDropdownMenu(
            caller=self.screen.ids.drop_item,
            items=menu_items,
            position="center",
            callback=self.set_item,
            width_mult=4,
        )

    def set_item(self, instance):
        self.screen.ids.drop_item.set_item(instance.text)

    def build(self):
        return self.screen


Test().run()
https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/menu-position-center.gif

API - kivymd.uix.menu

class kivymd.uix.menu.RightContent(**kwargs)

Same as IRightBody, but allows the widget to receive touch events instead of triggering the ListItem’s ripple effect

text
icon
class kivymd.uix.menu.MDMenuItem(**kwargs)

A one line list item.

icon
class kivymd.uix.menu.MDDropdownMenu(**kwargs)

Float layout class. See module documentation for more information.

items

See data.

items is a ListProperty and defaults to [].

width_mult

This number multiplied by the standard increment (56dp on mobile, 64dp on desktop, determines the width of the menu items.

If the resulting number were to be too big for the application Window, the multiplier will be adjusted for the biggest possible one.

width_mult is a NumericProperty and defaults to 1.

max_height

The menu will grow no bigger than this number. Set to 0 for no limit.

max_height is a NumericProperty and defaults to 0.

border_margin

Margin between Window border and menu.

border_margin is a NumericProperty and defaults to 4dp.

ver_growth

Where the menu will grow vertically to when opening. Set to None to let the widget pick for you. Available options are: ‘up’, ‘down’.

ver_growth is a OptionProperty and defaults to None.

hor_growth

Where the menu will grow horizontally to when opening. Set to None to let the widget pick for you. Available options are: ‘left’, ‘right’.

hor_growth is a OptionProperty and defaults to None.

background_color

Color of the background of the menu.

background_color is a ListProperty and defaults to [].

opening_transition

Type of animation for opening a menu window.

opening_transition is a StringProperty and defaults to ‘out_cubic’.

opening_time

Menu window opening animation time.

opening_time is a NumericProperty and defaults to 0.2.

caller

The widget object that caller the menu window.

caller is a ObjectProperty and defaults to None.

callback

The method that will be called when you click menu items.

callback is a ObjectProperty and defaults to None.

position

Menu window position relative to parent element. Available options are: ‘auto’, ‘center’, ‘bottom’.

position is a OptionProperty and defaults to ‘auto’.

use_icon_item

Whether to use menu items with an icon on the left.

use_icon_item is a BooleanProperty and defaults to True.

check_position_caller(self, instance, width, height)
create_menu_items(self)

Creates menu items.

set_menu_properties(self, interval)

Sets the size and position for the menu window.

open(self)

Animate the opening of a menu window.

on_touch_down(self, touch)

Receive a touch down event.

Parameters
touch: MotionEvent class

Touch received. The touch is in parent coordinates. See relativelayout for a discussion on coordinate systems.

Returns

bool If True, the dispatching of the touch event will stop. If False, the event will continue to be dispatched to the rest of the widget tree.

on_touch_move(self, touch)

Receive a touch move event. The touch is in parent coordinates.

See on_touch_down() for more information.

on_touch_up(self, touch)

Receive a touch up event. The touch is in parent coordinates.

See on_touch_down() for more information.

on_dismiss(self)
dismiss(self)