Search code examples
kivykivymdonpress

I want to bind kivy list-item with on_press:root.manager.current = 'screen1'


I am a beginner (Sorry for clumsy codes). I want to make codes such that whenever I click a menu icon in header, navbar toggle out. And list of items appears in the navbar. (this works) And when I click the item in navbar, it brings me to another screen (this doesn't work). Below are the codes. It shows 'NoneType' has no attribute of 'current'

from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivymd.theming import ThemableBehavior
from kivymd.uix.list import MDList
from kivy.uix.screenmanager import Screen, ScreenManager

navigation_helper = """
MDScreen:
    MDNavigationLayout:
        ScreenManager:
            MDScreen:
                MDBoxLayout:
                    orientation: 'vertical'
                    MDToolbar:
                        title: 'Title'
                        left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]]
                        elevation:10
                    Widget:
            Screen1:

        MDNavigationDrawer:
            id: nav_drawer
            ContentNavigationDrawer:
                id: content_drawer
                orientation: 'vertical'
                padding: "8dp"
                spacing: "8dp"
                
                AnchorLayout:
                    anchor_x: "left"
                    size_hint_y: None
                    height: avatar.height
                    
                    Image:
                        id: avatar
                        size_hint: None, None
                        size: "180dp", "100dp"
                        source: "logo.png"

                ScrollView:
                    DrawerList:
                        id: md_list

                        MDList:
                            OneLineIconListItem:
                                text: "Screen 1"
                                on_press: root.manager.current = 'screen1'
                                IconLeftWidget:
                                    icon: "account-multiple"
                                    
<Screen1>:
    name: 'screen1'
    MDLabel:
        text: 'Profile'
        halign: 'center'
"""

class Screen1(Screen):
    pass


sm = ScreenManager()
sm.add_widget(Screen1(name='screen1'))


class ContentNavigationDrawer(BoxLayout):
    pass


class DrawerList(ThemableBehavior, MDList):
    pass


class NavBar(MDApp):
    def build(self):
        screen = Builder.load_string(navigation_helper)
        self.theme_cls.primary_palette = 'Indigo'
        return screen

    def on_start(self):
        pass


NavBar().run()

Solution

  • By default root is None, so when you write on_press: root.manager.current = 'screen1' it raises the expected error, AttributeError.

    But also note that even if you remove it, you will get another error NameError as you've not given any reference to 'manager'.

    Thus the changes you need,

        MDNavigationLayout:
            ScreenManager:
                id: manager # Use it as id keeping the name as it is.
                MDScreen:
    

    and also,

                            MDList:
                                OneLineIconListItem:
                                    text: "Screen 1"
                                    on_press: manager.current = 'screen1'
                                    IconLeftWidget:
                                        icon: "account-multiple"