Search code examples
kivykivy-languagekivymd

AttributeError: 'kivy.properties.DictProperty' object has no attribute 'field'?


I am getting this error: " AttributeError: 'kivy.properties.DictProperty' object has no attribute 'field' "

I'm trying to create a dropdown menu with kivymd. On my .kv file i have this "id: field" and it keeps saying to me that " object has no attribute 'field' "

any help is welcome!

this is my .kv file:

<Box>:
    MDTextField:
        id: field
        pos_hint: {'center_x': .5, 'center_y': .5}
        size_hint_x: None
        width: "200dp"
        hint_text: "Password"
        on_focus: if self.focus: app.menu.open()

and this is my .py file:

from kivy.uix.boxlayout import BoxLayout
from kivy.clock import Clock
from kivymd.app import MDApp
from kivymd.uix.menu import MDDropdownMenu


class Box(BoxLayout):
    pass


class Projeto(MDApp):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.screen = Box
        menu_items = [{"icon": "git", "text": f"Item {i}"} for i in range(5)]
        self.menu = MDDropdownMenu(
            caller=self.screen.ids.field,
            items=menu_items,
            position="bottom",
            width_mult=4,
        )
        self.menu.bind(on_release=self.set_item)

    def set_item(self, instance_menu, instance_menu_item):
        def set_item(interval):
            self.screen.ids.field.text = instance_menu_item.text
            instance_menu.dismiss()

        Clock.schedule_once(set_item, 0.5)

    def build(self):
        return Box()


if __name__ == '__main__':
    Projeto().run()

Solution

  • You can fix that error by eliminating your __init__() method and moving some of that code into the build() method:

    class Projeto(MDApp):
    
        def set_item(self, instance_menu_item):
            def set_item(interval):
                self.screen.ids.field.text = instance_menu_item.text
                self.menu.dismiss()
    
            Clock.schedule_once(set_item, 0.5)
    
        def build(self):
            self.screen = Box()
            menu_items = [{"icon": "git", "text": f"Item {i}"} for i in range(5)]
            self.menu = MDDropdownMenu(
                caller=self.screen.ids.field,
                callback=self.set_item,
                items=menu_items,
                position="bottom",
                width_mult=4,
            )
            # self.menu.bind(on_release=self.set_item)  # use callback instead of bind
            return self.screen