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:\Users\alexa\PycharmProjects\TheFinalApp\venv\lib\site-packages\kivy\lang\builder.py", line 55, in custom_callback
exec(__kvlang__.co_value, idmap)
File "C:\Users\alexa\PycharmProjects\TheFinalApp\ardour.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 "kivy\weakproxy.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()
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