Search code examples
pythonuser-interfacekivykivy-languagekivymd

KivyMD - How can I navigate around Screens using both KivyMD BottomNavigationItems and Buttons within the Screens themselves?


I am at a loss with the Kivy ScreenManager (disclaimer - I am fairly new to this).

My aspiration is to build a basic app utilising the following:

MDToolbar with a right_action_item to load a SettingsScreen which can be called from anywhere within the app.

KivyMD BottomNavigationToolbar to define 4 main screens (HomeScreen, PlantsScreen, TasksScreen, WikiScreen).

Within PlantsScreen there will be a ScrollView containing an MDList of numerous MDCards/Buttons. The function of each of these buttons would be to call another Screen within PlantsScreen i.e.:

PlantsScreen:
    ScrollView:
        MDList:
            MDTextButton:
                on_press: # display Screen2_1
            MDTextButton:
                on_press: # display Screen2_2
            MDTextButton:
                on_press: # display Screen2_3
            MDTextButton:
                on_press: # display Screen2_4

I am assuming this would need to be done view a new instance of a ScreenManager which sits as a Child of PlantsScreen. However I am having issues with accessing the Screens.

Currently my code snippets are as follows(excluding imports etc):

.py

Builder.load_file('.kv files/Plants_Screen.kv')

class HomeScreen(MDScreen):
pass

class PlantsScreen(MDBoxLayout):
    class Screen2_1(MDScreen):
        pass
    class Screen2_2(MDScreen):
        pass
    class Screen2_3(MDScreen):
        pass
    class Screen2_4(MDScreen):
        pass

class GardenTools(MDApp):
    def build(self):
        return Builder.load_file('.kv files/main.kv')


GardenTools().run()

.kv

BoxLayout:
    orientation: 'vertical'

    MDToolbar:
        title: 'Bottom navigation'
        md_bg_color: .2, .2, .2, 1
        specific_text_color: 1, 1, 1, 1

    MDBottomNavigation:
        panel_color: .2, .2, .2, 1

        MDBottomNavigationItem:
            name: 'HomeScreen'
            text: 'Home'
            icon: 'home'

            MDLabel:
                text: 'Home'
                halign: 'center'

        MDBottomNavigationItem:
            name: 'PlantsScreen'
            text: 'Plants'
            icon: 'carrot'

            PlantsScreen

        MDBottomNavigationItem:
            name: 'TasksScreen'
            text: 'Tasks'
            icon: 'note-multiple'

            MDLabel:
                text: 'Tasks'
                halign: 'center'

        MDBottomNavigationItem:
            name: 'WikiScreen'
            text: 'Wiki'
            icon: 'web'

            MDLabel:
                text: 'Wiki'
                halign: 'center'
<PlantsScreen>:
    ScreenManager:
        id: sm2
        Plants_Home:
        Screen2_1:
        Screen2_2:
            name: 'Screen2_2'
            MDLabel:
                text: 'Screen2_2'
        Screen2_3:
        Screen2_4:

<Plants_Home>:
    name: 'Plants_Home'
    MDLabel:
        text: 'Plants_Home'
    MDTextButton:
        text: 'Screen2_1'
        on_press: root.sm2.current(Screen2_1)

<Screen2_1>:
    name: 'Screen2_1'
    MDLabel:
        text: 'Screen2_1'

<Screen2_2>:

<Screen2_3>:

<Screen2_4>:

Question 1: Currently the Button on_press: sm2.current(Screen2_1) returns **NameError: name 'sm2' is not defined.**I am unsure how to fix this so the Screens switch?

Question 2: What would the best way to create and open a SettingsScreen using the right_action_item of the MDToolbar that can be called at any time?


Solution

  • Q1:
    on_press: root.manager.current= 'screen name'