How to program a reusable button in KivyMD?

239 Views Asked by At

I'm trying to create a "BackButton" that will be present in several screens, will have the same icon, color, and position and will always perform the same action (send the user to the previous page). To reduce the chance of error and for matters of time economy, I'd like to programe it once and then load it when necessary from a .kv file. Here is a simplified example of what I want to do.

main.py

from kivymd.app import MDApp
from kivy.lang.builder import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivymd.uix.button import MDIconButton

class HomeScreen(Screen):
    pass

class ProfileScreen(Screen):
    pass

sm = ScreenManager()
sm.add_widget(HomeScreen(name='home'))
sm.add_widget(ProfileScreen(name='profile'))

class DemoApp(MDApp):
    def build(self):
        screen = Builder.load_file('main.kv')
        return screen

DemoApp().run()

main.kv

#: include kv/homescreen.kv
#: include kv/profilescreen.kv
#: include kv/button.kv

ScreenManager:
    HomeScreen:
    ProfileScreen:

kv/homescreen.kv

<HomeScreen>:
    name: 'home'
    MDIconButton:
        icon: 'account'
        pos_hint: {'center_x':0.5,'center_y':0.6}
        on_press: root.manager.current = 'profile'
        on_press: root.manager.transition.direction = 'left'

kv/profile.kv

<ProfileScreen>:
    name: 'profile'
    MDLabel:
        text: 'profile'
        halign: 'center'
    BackButton:

button.kv

<BackButton>:
    MDIconButton:
        icon: 'arrow-left-thick'
        pos_hint: {'center_x':0.5,'center_y':0.1}
        on_press: root.manager.transition.direction = 'right'
        on_press: root.manager.current = 'DESTINATION'

Whenever I run this I get:

AttributeError: 'BackButton' object has no attribute 'manager

which I don't understand. The button should be able to take a variable for root.manager.current as this will be the only variable that will change from screen to screen. Someone has a suggestion?

1

There are 1 best solutions below

0
On

The root variable is a pre-defined variable in kv that refers to the the root of the enclosing rule. So, your root in that kv file refers to BackButton, which has no manager attribute. Try this:

<BackButton>:
    MDIconButton:
        icon: 'arrow-left-thick'
        pos_hint: {'center_x':0.5,'center_y':0.1}
        on_press: app.root.manager.transition.direction = 'right'
        on_press: app.root.manager.current = 'DESTINATION'

The app is also predefined kv variable the refers to the current App, and the App has a root which is the ScreenManager that you assigned.