Home > database >  Kivy: AttributeError: '...' object has no attribute '...', but it has
Kivy: AttributeError: '...' object has no attribute '...', but it has

Time:06-21

I have this TaskTemplate with some Buttons, TexInput, etc. I will put just a piece of code for an easy understanding.

class TaskTemplate(BoxLayout, Button):
    task_name = StringProperty()
    def __init__(self):
        super(TaskTemplate, self).__init__()
        self.update_state = 'down'
<TaskTemplate>:
    RelativeLayout:
        CheckBox:
            state: root.update_state

If I use TaskTemplate as root class it works, I can change the state of the CheckBox with that parameter.
If I add TaskTemplate here:

MainScreen:
<MainScreen>:
    BoxLayout:
        ScrollView:
            GridLayout:
                id: here_add_task_template

I get this error which has no end:

Traceback (most recent call last):
   File "C:\Users\barbu\OneDrive\Desktop\Final App 2\venv\lib\site-packages\kivy\lang\builder.py", line 240, in create_handler
     return eval(value, idmap), bound_list
   File "C:\Users\barbu\OneDrive\Desktop\Final App 2\middleScreen.kv", line 122, in <module>
     state: root.update_state
   File "kivy\weakproxy.pyx", line 32, in kivy.weakproxy.WeakProxy.__getattr__
 AttributeError: 'TaskTemplate' object has no attribute 'update_state'
 
 During handling of the above exception, another exception occurred:
 
 Traceback (most recent call last):
   File "C:\Users\barbu\OneDrive\Desktop\Final App 2\venv\lib\site-packages\kivy\lang\builder.py", line 694, in _apply_rule
     value, bound = create_handler(
   File "C:\Users\barbu\OneDrive\Desktop\Final App 2\venv\lib\site-packages\kivy\lang\builder.py", line 243, in create_handler
     raise BuilderException(rule.ctx, rule.line,
 kivy.lang.builder.BuilderException: Parser: File "C:\Users\barbu\OneDrive\Desktop\Final App 2\middleScreen.kv", line 122:
 ...
     120:#                root.update_index()
     121:#                root.save_in_json(self)
 >>  122:            state: root.update_state
     123:
     124:        Button:
 ...
 AttributeError: 'TaskTemplate' object has no attribute 'update_state'
   File "C:\Users\barbu\OneDrive\Desktop\Final App 2\venv\lib\site-packages\kivy\lang\builder.py", line 240, in create_handler
     return eval(value, idmap), bound_list
   File "C:\Users\barbu\OneDrive\Desktop\Final App 2\middleScreen.kv", line 122, in <module>
     state: root.update_state
   File "kivy\weakproxy.pyx", line 32, in kivy.weakproxy.WeakProxy.__getattr__
 
 
 During handling of the above exception, another exception occurred:
 
 Traceback (most recent call last):
   File "C:\Users\barbu\OneDrive\Desktop\Final App 2\main.py", line 246, in <module>
     MainApp().run()
   File "C:\Users\barbu\OneDrive\Desktop\Final App 2\venv\lib\site-packages\kivy\app.py", line 955, in run
     runTouchApp()
   File "C:\Users\barbu\OneDrive\Desktop\Final App 2\venv\lib\site-packages\kivy\base.py", line 574, in runTouchApp
     EventLoop.mainloop()
   File "C:\Users\barbu\OneDrive\Desktop\Final App 2\venv\lib\site-packages\kivy\base.py", line 341, in mainloop
     self.window.mainloop()
   File "C:\Users\barbu\OneDrive\Desktop\Final App 2\venv\lib\site-packages\kivy\core\window\window_sdl2.py", line 757, in mainloop
     if self.dispatch('on_key_down', key,
   File "kivy\_event.pyx", line 727, in kivy._event.EventDispatcher.dispatch

CodePudding user response:

Your update_state is just an instance variable of TaskTemplate. So using state: root.update_state in your kv just sets the initial state of the CheckBox. Changing that variable will have no effect on the CheckBox. If you want the CheckBox to reflect changes to the value of update_state, then you have two choices.

  1. Write python code that will update the CheckBox whenever you change the value of update_state.
  2. Change update_state to a Property. Then kv will add the binding to update the CheckBox whenever update_state is changed.

In order to implement #2 above simply change:

class TaskTemplate(BoxLayout, Button):
    task_name = StringProperty()
    def __init__(self):
        super(TaskTemplate, self).__init__()
        self.update_state = 'down'

to:

class TaskTemplate(BoxLayout, Button):
    update_state = StringProperty('down')
    task_name = StringProperty()

Note: unless you have something more planned for TaskTemplate, there is no need for it to extend Button.

  • Related