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 = '''
MDScreen:

    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 = [
            {
                "text": f"Item {i}",
                "viewclass": "OneLineListItem",
                "on_release": lambda x=f"Item {i}": self.menu_callback(x),
            } for i in range(5)
        ]
        self.menu = MDDropdownMenu(
            caller=self.screen.ids.button,
            items=menu_items,
            width_mult=4,
        )

    def menu_callback(self, text_item):
        print(text_item)

    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()

Customization of menu item#

Menu items are created in the same way as items for the RecycleView class.

from kivy.lang import Builder
from kivy.metrics import dp
from kivy.properties import StringProperty

from kivymd.app import MDApp
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.list import IRightBodyTouch, OneLineAvatarIconListItem
from kivymd.uix.menu import MDDropdownMenu

KV = '''
<RightContentCls>
    disabled: True
    adaptive_size: True
    pos_hint: {"center_y": .5}

    MDIconButton:
        icon: root.icon
        user_font_size: "16sp"
        md_bg_color_disabled: 0, 0, 0, 0

    MDLabel:
        text: root.text
        font_style: "Caption"
        adaptive_size: True
        pos_hint: {"center_y": .5}


<Item>

    IconLeftWidget:
        icon: root.left_icon

    RightContentCls:
        id: container
        icon: root.right_icon
        text: root.right_text


MDScreen:

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


class RightContentCls(IRightBodyTouch, MDBoxLayout):
    icon = StringProperty()
    text = StringProperty()


class Item(OneLineAvatarIconListItem):
    left_icon = StringProperty()
    right_icon = StringProperty()
    right_text = StringProperty()


class Test(MDApp):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.screen = Builder.load_string(KV)
        menu_items = [
            {
                "text": f"Item {i}",
                "right_text": f"R+{i}",
                "right_icon": "apple-keyboard-command",
                "left_icon": "git",
                "viewclass": "Item",
                "height": dp(54),
                "on_release": lambda x=f"Item {i}": self.menu_callback(x),
            } for i in range(5)
        ]
        self.menu = MDDropdownMenu(
            caller=self.screen.ids.button,
            items=menu_items,
            width_mult=4,
        )

    def menu_callback(self, text_item):
        print(text_item)

    def build(self):
        return self.screen


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

Position#

Bottom position#

See also

position

from kivy.lang import Builder
from kivy.metrics import dp
from kivy.properties import StringProperty

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

KV = '''
<IconListItem>

    IconLeftWidget:
        icon: root.icon


MDScreen

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


class IconListItem(OneLineIconListItem):
    icon = StringProperty()


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

    def set_item(self, text__item):
        self.screen.ids.field.text = text__item
        self.menu.dismiss()

    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 kivy.metrics import dp
from kivy.properties import StringProperty

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

KV = '''
<IconListItem>

    IconLeftWidget:
        icon: root.icon


MDScreen

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


class IconListItem(OneLineIconListItem):
    icon = StringProperty()


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

    def set_item(self, text_item):
        self.screen.ids.drop_item.set_item(text_item)
        self.menu.dismiss()

    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.menu#

class kivymd.uix.menu.menu.MDDropdownMenu(**kwargs)#
Events:

on_release

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

header_cls#

An instance of the class (Kivy or KivyMD widget) that will be added to the menu header.

New in version 0.104.2.

See Header for more information.

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

header_cls is a ObjectProperty and defaults to None.

items#

See data.

items = [
    {
        "viewclass": "OneLineListItem",
        "height": dp(56),
        "text": f"Item {i}",
    }
    for i in range(5)
]
self.menu = MDDropdownMenu(
    items=items,
    ...,
)
https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/menu-items.png

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.

self.menu = MDDropdownMenu(
    width_mult=4,
    ...,
)
https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/menu-width-mult-4.png
self.menu = MDDropdownMenu(
    width_mult=8,
    ...,
)
https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/menu-width-mult-8.png

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.

self.menu = MDDropdownMenu(
    max_height=dp(112),
    ...,
)
https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/menu-max-height-112.png
self.menu = MDDropdownMenu(
    max_height=dp(224),
    ...,
)
https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/menu-max-height-224.png

max_height is a NumericProperty and defaults to 0.

border_margin#

Margin between Window border and menu.

self.menu = MDDropdownMenu(
    border_margin=dp(4),
    ...,
)
https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/menu-border-margin-4.png
self.menu = MDDropdownMenu(
    border_margin=dp(24),
    ...,
)
https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/menu-border-margin-24.png

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’.

self.menu = MDDropdownMenu(
    ver_growth="up",
    ...,
)
https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/menu-ver-growth-up.gif
self.menu = MDDropdownMenu(
    ver_growth="down",
    ...,
)
https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/menu-ver-growth-down.gif

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’.

self.menu = MDDropdownMenu(
    hor_growth="left",
    ...,
)
https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/menu-hor-growth-left.gif
self.menu = MDDropdownMenu(
    hor_growth="right",
    ...,
)
https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/menu-hor-growth-right.gif

hor_growth is a OptionProperty and defaults to None.

background_color#

Color of the background of the menu.

self.menu = MDDropdownMenu(
    background_color=self.theme_cls.primary_light,
    ...,
)
https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/menu-background-color.png

background_color is a ColorProperty and defaults to None.

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 and you can set it to 0 if you don’t want animation of menu opening.

opening_time is a NumericProperty and defaults to 0.2.

caller#

The widget object that calls the menu window.

caller is a ObjectProperty and defaults to None.

position#

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

See Position for more information.

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

position is a OptionProperty and defaults to ‘auto’.

radius#

Menu radius.

self.menu = MDDropdownMenu(
    radius=[24, 0, 24, 0],
    ...,
)
https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/menu-radius.png

radius is a VariableListProperty and defaults to ‘[dp(7)]’.

elevation#

Elevation value of menu dialog.

New in version 1.0.0.

self.menu = MDDropdownMenu(
    elevation=16,
    ...,
)
https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/menu-elevation.png

elevation is an NumericProperty and defaults to 10.

check_position_caller(self, instance_window: WindowSDL, width: int, height: int)#

Called when the application root window is resized.

set_menu_properties(self, interval: Union[int, float] = 0)#

Sets the size and position for the menu window.

ajust_radius(self, interval: Union[int, float])#

Adjusts the radius of the first and last items in the menu list according to the radius that is set for the menu.

adjust_position(self)#

Returns value ‘auto’ for the menu position if the menu position is out of screen.

open(self)#

Animate the opening of a menu window.

on_header_cls(self, instance_dropdown_menu, instance_user_menu_header)#

Called when a value is set to the header_cls parameter.

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)#

Called when the menu is closed.

dismiss(self, *args)#

Closes the menu.