I'm learning KivyMD and I'm trying to add a dropdown menu but I get this error. It's probably because of my wrong usage of ids but I still cant figure it out. Here is my main py code:
from kivymd.app import MDApp
from kivy.lang import Builder
from kivymd.uix.screenmanager import ScreenManager
from kivymd.uix.screen import Screen
from kivymd.uix.menu import MDDropdownMenu
from kivy.metrics import dp
from kivy.core.window import Window
Window.size = (500, 800)
class HomePage(Screen):
pass
class SecondPage(Screen):
pass
class App(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.screen = Builder.load_file("kivy.kv")
items_d = ['Settings', 'Profile', 'Log Out', '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):
self.theme_cls.primary_palette = 'Red'
self.theme_cls.primary_hue = '500'
self.theme_cls.theme_style = 'Dark'
sm = ScreenManager()
sm.add_widget(HomePage(name='first'))
sm.add_widget(SecondPage(name='second'))
return self.screen
App().run()
and here is the kv file:
#:kivy 2.1.0
ScreenManager:
HomePage:
SecondPage:
<HomePage>
name: 'first'
MDNavigationLayout:
ScreenManager:
Screen:
BoxLayout:
orientation:'vertical'
MDTopAppBar:
id:tool1
title: 'Home Page'
left_action_items: [['menu', lambda x: nav_drawer.set_state('toggle')]]
right_action_items: [['dots-vertical'], lambda x: app.menu.open()]
elevation: 3
MDLabel:
text: "."
MDBottomAppBar:
MDTopAppBar:
icon: 'apps'
mode: 'center'
type: 'bottom'
MDNavigationDrawer:
id: nav_drawer
ScrollView:
MDList:
OneLineIconListItem:
text: 'Home Page'
on_press: nav_drawer.set_state('close')
on_press: root.manager.current = 'first'
IconLeftWidgetWithoutTouch:
icon:'bluetooth'
OneLineIconListItem:
text: 'Content Page'
on_press: root.manager.current = 'second'
on_press: nav_drawer.set_state('close')
IconLeftWidgetWithoutTouch:
icon:'content-copy'
<SecondPage>
name: 'second'
MDNavigationLayout:
ScreenManager:
Screen:
BoxLayout:
orientation:'vertical'
MDTopAppBar:
id:tool1
title: 'Content Page'
left_action_items: [['menu', lambda x: nav_drawer.set_state('toggle')]]
right_action_items: [['dots-vertical'], lambda x: app.menu.open()]
elevation: 3
MDLabel:
text: "."
MDBottomAppBar:
MDTopAppBar:
type: 'bottom'
icon: 'apps'
mode: 'center'
left_action_items: [['information']]
MDNavigationDrawer:
id: nav_drawer
ScrollView:
MDList:
OneLineIconListItem:
text: 'Home Page'
on_press: nav_drawer.set_state('close')
on_press: root.manager.current = 'first'
IconLeftWidgetWithoutTouch:
icon:'bluetooth'
OneLineIconListItem:
text: 'Second Page'
on_press: nav_drawer.set_state('close')
on_press: root.manager.current = 'second'
IconLeftWidgetWithoutTouch:
icon:'wifi'
I don't know why exactly but maybe because of self.screen doesn't really contain the ids? And please tell me what to use instead if I'm using wrong methods.
You are incorrectly trying to access the
tool1id. First, note that theidsdefined in thekvfile become part of theidsdictionary of the root of the rule where thatidis defined. So thetool1id(which is defined twice) ends up in theidsof theHomePageand also in theidsof theSecondPage. So you must reference thatidthrough the containing object. Assuming you want to reference thetool1defined inHomePage, just change:to:
Unrelated, but you can eliminate the lines:
since their result is unused.