Hello. I am currently working on implementing an MDDropdownMenu which opens when the user clicks the right action item on the MDToolbar. Beside simple label items as they are shown in the kitchen-sink demo I would like extended items which shoe an MDSwitch next to them.
Here is my code so far (Kivy Version 1.11.1, KivyMD latest master from github):
main.py
from kivymd.app import MDApp
from kivymd.uix.menu import MDMenuItem
class MySwitchableMenuItem(MDMenuItem):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def on_touch_up(self, instance):
self.active = False if self.children[0].active else True
class MainApp(MDApp):
def __init__(self, **kwargs):
self.title = "KivyMD MDDropdownMenu Demo"
super().__init__(**kwargs)
self.menu_items = [
{"viewclass": "MySwitchableMenuItem",
"text": "MyItem1", "active": False},
{"viewclass": "MySwitchableMenuItem",
"text": "MyItem2", "active": True}
]
def callback_switch_triggered(self, label, active):
print("callback_switch_triggered: " + label)
if label == "MyItem1":
if active:
self.menu_items[0]["active"] = True
else:
self.menu_items[0]["active"] = False
elif label == "MyItem2":
if active:
self.menu_items[1]["active"] = True
else:
self.menu_items[1]["active"] = False
if __name__ == "__main__":
MainApp().run()
main.kv
#:kivy 1.11.1
#:import MDDropdownMenu kivymd.uix.menu.MDDropdownMenu
#:import MDToolbar kivymd.uix.toolbar.MDToolbar
<MySwitchableMenuItem>
active: False
MDSwitch:
size_hint: None, None
size: dp(36), dp(48)
pos_hint: {'center_x': .3, 'center_y': .4}
active: self.parent.active
on_active:
app.callback_switch_triggered(self.parent.text, self.active)
BoxLayout:
orientation: 'vertical'
MDToolbar:
id: toolbar
title: app.title
pos_hint: {"top": 1}
right_action_items: [['dots-vertical', lambda instance: MDDropdownMenu(items=app.menu_items, width_mult=3, ver_growth='down', hor_growth='left', pos=instance.pos).open(instance)]]
Widget:
There are two problems with my code:
- When opening the Dropdown menu, the callback method for both menu entries is called 57 times! However it should only be executed when the state of the switch changes
- When clicking on the menu item label to change the state of the switch, the other switch is affected aswell (clicking directly on the switch "thumb" the state changes correctly)
How can I change my code so that the callback is only executed when the state of the switch changes and that clicking the menu item label only the corresponding switch is affected?