Shourov
Shourov

Reputation: 69

kivyMD: How can I create dropdown menu with toolbar action item?

I am a beginner in kivymd. I was trying to create an event like real-life mobile application has. Other word I was trying to something like Dropdown menu, when I press on Toolbar action item in python kivymd. My requirement exact like the image given bellow.

enter image description here enter image description here

I am only able to implement dropdown menu simply. This is my simple code,

from kivy.lang import Builder
from kivy.metrics import dp
from kivy.properties import StringProperty
from kivymd.uix.list import OneLineListItem
from kivymd.app import MDApp
from kivymd.uix.menu import MDDropdownMenu

KV = '''
MDScreen:
    MDDropDownItem:
        id: drop_item
        pos_hint: {'center_x': .5, 'center_y': .5}
        text: 'Select'
        on_release: app.menu.open()

'''

class Test(MDApp):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.screen = Builder.load_string(KV)
        d_items = ['Snapshot','Settings','History','Logout','Exit']
        menu_items = [
            {
                "viewclass": "OneLineListItem",
                "text": i,
                "height": dp(40),
                "on_release": lambda x=i: self.set_item(x),
            } for i in d_items
        ]
        self.menu = MDDropdownMenu(
            caller=self.screen.ids.drop_item,
            items=menu_items,
            position="center",
            width_mult=2,
        )
        self.menu.bind()

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


    def build(self):
        return self.screen


Test().run()

Now I want to implement the event just like shown in two images. How can I implement this in kivymd?

Upvotes: 0

Views: 2863

Answers (2)

Shourov
Shourov

Reputation: 69

The approximate solution

from kivy.lang import Builder
from kivy.metrics import dp
from kivymd.app import MDApp
from kivymd.uix.menu import MDDropdownMenu
from kivy.core.window import Window

Window.size=(340,610)
KV = '''
MDScreen:

    MDToolbar:
        id:tool1
        title:'My Demo App'
        pos_hint:{'top':1}
        right_action_items : [["dots-vertical", lambda x: app.menu.open()]]

'''


class Test(MDApp):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.screen = Builder.load_string(KV)
        items_d = ['Snapshot','Settings','History','Logout','Exit']
        menu_items = [
            {
                "text": f"{i}",
                "viewclass": "OneLineListItem",
                "height": dp(40),
                "on_release": lambda x=f"{i}": self.menu_callback(x),
            } for i in items_d
        ]
        self.menu = MDDropdownMenu(
            caller=self.screen.ids.tool1,
            items=menu_items,
            width_mult=2,
        )

    def menu_callback(self, text_item):
        print(text_item)
        self.menu.dismiss()

    def build(self):
        return self.screen


Test().run()

enter image description here

Upvotes: 1

user13676212
user13676212

Reputation:

Try this, it has been hard to correctly locate the menu in the screen, you will have to calculate the right location based on the mobile device resolution:

from kivy.lang import Builder
from kivy.metrics import dp
from kivy.properties import StringProperty
from kivymd.uix.list import OneLineListItem
from kivymd.app import MDApp
from kivymd.uix.menu import MDDropdownMenu
from kivymd.uix.label import MDLabel
from kivy.core.window import Window

import os
if os.path.exists("_python_bundle/")==False:
    try:
        Window.size=(350,600)
    except:
        pass

from kivy.lang import Builder
from kivy.properties import StringProperty, NumericProperty
from kivy.uix.behaviors import ButtonBehavior
from kivy.uix.widget import Widget

from kivymd.uix.behaviors import RectangularRippleBehavior
from kivymd.uix.boxlayout import MDBoxLayout
from kivy.uix.boxlayout import BoxLayout
from kivymd.theming import ThemableBehavior

KV = '''
Screen:
    ScreenManager:
        Screen:
            name: "screen1"
            MDToolbar:
                pos_hint: {'top': 1}
                title: "App jbsidis"
                right_action_items: [["dots-vertical", lambda x:app.menu.open()]]
                left_action_items: [["menu", lambda x:app.menu.open()]]
    FloatLayout:
        MDDropDownItem_jbsidis:
            id: drop_item
            size: 1, 0
            pos_hint: {'center_x': .42, 'center_y': .72}
            #pos_hint: {'center_x': .320215, 'center_y': .68} #398 #complex location for menu by jbsidis, you must calculate this on a cellphone device

<MDDropDownItem_jbsidis>
    orientation: "vertical"
    adaptive_size: True
    spacing: "5dp"
    padding: "-20dp", "0dp", "0dp", 0
    
    FloatLayout:
        adaptive_size: True
        padding: dp(-10)
        spacing: "10dp"
        #pos_hint: {'center_x': .6}

        MDLabel:
            id: label_item
            size_hint: None, None
            #size: self.texture_size
            color: root.theme_cls.text_color
            font_size: root.font_size
<jbsidis_item>
    MDLabel:
        text: root.text
    


'''

class MDDropDownItem_jbsidis(ThemableBehavior, RectangularRippleBehavior, ButtonBehavior, MDBoxLayout):
    text = StringProperty()
    current_item = StringProperty()
    font_size = NumericProperty("18sp")
    def on_text(self, instance, value):
        self.ids.label_item.text = value

    def set_item(self, name_item):
        self.ids.label_item.text = name_item
        self.current_item = name_item

class jbsidis_item(MDBoxLayout):
    text = StringProperty()
    pass


class JBSIDIS(MDApp):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.screen = Builder.load_string(KV)
        d_items = ['Snapshot','Settings','History','Logout','Exit']
        menu_items = [
            {
                "viewclass": "MDDropDownItem_jbsidis",
                "markup": True,
                "text": "[b]"+i,
                "height": dp(30),
                "divider": None,
                "on_release": lambda x=i: self.set_item(x),
            } for i in d_items
        ]
        self.menu = MDDropdownMenu(
            caller=self.screen.ids.drop_item,
            items=menu_items,
            position="center",
            width_mult=3.3,
            hor_growth="right",
            opening_time=2,
        )
##        self.menu = MDDropdownMenu(
##            caller=self.screen.ids.drop_item,
##            items=menu_items,
##            position="center",
##            width_mult=3.3,
##            hor_growth="right",
##            opening_time=2,
##            background_color=[.1,0,1,.5]
##        )
        #to change the bg color of the menu just  add remove the line "background_color=[.1,0,1,.5]"
        self.menu.bind()

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


    def build(self):
        return self.screen


JBSIDIS().run()

Pictures: enter image description here

enter image description here

Upvotes: 1

Related Questions