KivyMD issue with Menu (MDDropdownMenu) operation on multiple screens

268 views
Skip to first unread message

Honey Budger

unread,
Mar 13, 2021, 6:35:15 AM3/13/21
to Kivy users support
When working with a single screen, everything works fine. But when I try to add MDDropdownMenu to any other screen (when I add ScreenManager and the second screen), it gives:
AttributeError: 'super' object has no attribute '__getattr__'
Please help me to understand and resolve this issue. Here is the code itself:
from kivy.lang import Builder
from kivymd.app import MDApp
from kivymd.uix.menu import MDDropdownMenu
from kivy.uix.screenmanager import ScreenManager, Screen

kv = '''
ScreenManager:
FirstScreen:
SecondScreen:

<FirstScreen>
name: 'first'
MDRaisedButton:
id: button
text: "PRESS ME"
pos_hint: {"center_x": .5, "center_y": .5}
on_release: root.menu.open()

<SecondScreen>
name: 'second'
'''
class FirstScreen(Screen):
def btn_show(self):
menu_items = [{"text": f"Item {i}"} for i in range(5)]
self.menu = MDDropdownMenu(
caller=self.ids.button, items=menu_items, width_mult=4
)
self.menu.bind(on_release=self.menu_callback)

def menu_callback(self, instance_menu, instance_menu_item):
print(instance_menu, instance_menu_item)

class SecondScreen(Screen):
pass

class Test(MDApp):
def build(self):
screen = Builder.load_string(kv)
return screen

sm = ScreenManager()
sm.add_widget(FirstScreen(name='first'))
sm.add_widget(SecondScreen(name='second'))

Test().run()

ElliotG

unread,
Mar 21, 2021, 5:03:22 PM3/21/21
to Kivy users support
The Method btn_show() is never executed so self.menu is not created.  When the button is pressed root.menu does not exist, so you get an attribute error.
Changning btn_show to on_kv_post, runs the code when the screen is instanced, then the rest of the code works.  You have some redundant code creating screens, I commented that out.

from kivy.lang import Builder
from kivymd.app import MDApp
from kivymd.uix.menu import MDDropdownMenu
from kivy.uix.screenmanager import ScreenManager, Screen

kv = '''
ScreenManager:
    FirstScreen:
    SecondScreen:

<FirstScreen>
    name: 'first'
    MDRaisedButton:
        id: button
        text: "PRESS ME"
        pos_hint: {"center_x": .5, "center_y": .5}
        on_release: root.menu.open()

<SecondScreen>
    name: 'second'
'''


class FirstScreen(Screen):
    def on_kv_post(self, base_widget):  
        menu_items = [{"text": f"Item {i}"} for i in range(5)]
        self.menu = MDDropdownMenu(
            caller=self.ids.button, items=menu_items, width_mult=4
        )
        self.menu.bind(on_release=self.menu_callback)

    def menu_callback(self, instance_menu, instance_menu_item):
        print(instance_menu, instance_menu_item)


class SecondScreen(Screen):
    pass


class Test(MDApp):
    def build(self):
        screen = Builder.load_string(kv)
        return screen


# sm = ScreenManager()
# sm.add_widget(FirstScreen(name='first'))
# sm.add_widget(SecondScreen(name='second'))

Test().run()

Reply all
Reply to author
Forward
0 new messages