Kivy – AttributeError: 'DialogContent' object has no attribute 'manager'

Question:

When I close the Dialog Box using the ‘Cancel’ Button or try to add a task using the ‘Save’ button, it creates an attribute error saying that DialogContent doesn’t have an attribute called manager. I wanted to reference the close_dialog or the add_task from my RoutineCreation screen using the root.manager.get_screen function and I came across this error.

File "kivy_event.pyx", line 727, in kivy._event.EventDispatcher.dispatch
   File "kivy_event.pyx", line 1307, in kivy._event.EventObservers.dispatch
   File "kivy_event.pyx", line 1191, in kivy._event.EventObservers._dispatch
   File "C:UsersalexaPycharmProjectsTheFinalAppvenvlibsite-packageskivylangbuilder.py", line 55, in custom_callback
     exec(__kvlang__.co_value, idmap)
   File "C:UsersalexaPycharmProjectsTheFinalAppardour.kv", line 91, in <module>
     on_release: root.manager.get_screen('RoutineCreation').add_task(task_text, date_text.text), root.manager.get_screen('RoutineCreation').close_dialog()
   File "kivyweakproxy.pyx", line 32, in kivy.weakproxy.WeakProxy.__getattr__
 AttributeError: 'DialogContent' object has no attribute 'manager'

**My Code:**

class Ardour(MDApp):
    pass

class RoutineCreation(Screen):

    routine_dialog = None

    def show_routine_dialog(self):
        if not self.routine_dialog:
            self.routine_list_dialog = MDDialog(
                title="Routine Creation",
                type="custom",
                content_cls=DialogContent(),
            )

        self.routine_list_dialog.open()

    def close_dialog(self, *args):
        self.routine_list_dialog.dismiss()

    def add_task(self, task, task_date):
        print(task.text, task_date)
        task.text = ''
    pass

class DialogContent(MDBoxLayout):

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.ids.date_text.text = str(datetime.now().strftime('%A %d %B %Y'))

    def show_date_picker(self):
        date_dialog = MDDatePicker()
        date_dialog.bind(on_save = self.on_save)
        date_dialog.open()

    def on_save(self, instance, value, date_range):
        date = value.strftime('%A %d %B %Y')
        self.ids.date_text.text = str(date)
    pass

**My .kv File**

<RoutineCreation>:

    RectTwo:
    OrangeBar:
    OrangeBarTwo:
    Image:
        source: 'image/routinelabel.png'
        size: '300dp', '100dp'
        pos_hint: {'center_x': .5, 'center_y': .88}

    MDList:
        id: the_container

    Button:
        size_hint: None, None
        size: '300dp', '100dp'
        pos_hint: {'center_x': .5, 'center_y': .5}
        on_release: root.manager.get_screen('RoutineCreation').show_routine_dialog()
        background_color: 0, 0, 0, 0
        Image:
            source: 'image/addplan.png'
            center_x: self.parent.center_x
            center_y: self.parent.center_y
            size: self.parent.size

    Button:
        size_hint: None, None
        size: '200dp', '50dp'
        pos_hint: {'center_x': .275, 'center_y':  .125}
        background_color: 0, 0, 0, 0
        on_release:
            app.root.current = 'MenuScreen'
        Image:
            source: 'image/finish.png'
            center_x: self.parent.center_x
            center_y: self.parent.center_y
            size: self.parent.size

    Button:
        size_hint: None, None
        size: '200dp', '50dp'
        pos_hint: {'center_x': .725, 'center_y':  .125}
        background_color: 0, 0, 0, 0
        on_release:
            app.root.current = 'ChoiceScreen'
        Image:
            source: 'image/cancel.png'
            center_x: self.parent.center_x
            center_y: self.parent.center_y
            size: self.parent.size


<DialogContent>:

    orientation: 'vertical'
    spacing: '10dp'
    size_hint: 1, None
    height: '130dp'

    GridLayout:
        rows: 1

        MDTextField:
            id: task_text
            hint_text: 'Add Routine'
            pos_hint: {'center_y': .4}
            max_text_length: 40
            on_text_validate: root.get_screen('RoutineCreation').add_task(task_text, date_text.text)

        MDIconButton:
            icon: 'calendar'
            on_release: root.show_date_picker()
            padding: '10dp'

    MDLabel:
        spacing: '10dp'
        id: date_text

    BoxLayout:
        orientation: 'vertical'
        MDRaisedButton:
            text: 'Save'
            on_release: root.manager.get_screen('RoutineCreation').add_task(task_text, date_text.text), root.manager.get_screen('RoutineCreation').close_dialog()
        MDFlatButton:
            text: 'Cancel'
            on_release: root.manager.get_screen('RoutineCreation').close_dialog()
Asked By: Alexander Alico

||

Answers:

According to the kv lang documentation of the the root keyword:

This keyword is available only in rule definitions and represents the
root widget of the rule (the first instance of the rule)

So within your <DialogContent>: rule, the root refers to the DialogContent instance.

However, the same documentation says of the app keyword:

This keyword always refers to your app instance.

So, you probably want to replace:

root.manager.get_screen

with:

app.root.manager.get_screen
Answered By: John Anderson
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.