'AttributeError: object has no attribute 'ids'

I am new in kivy and I am trying to change image of float layout with a button I tried everything I can but it didn't worked out.

I am getting the below error AttributeError: 'Chat_Bot' object has no attribute 'ids'

May be I need to extend the class but I am not sure

Below is my main.py file

from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.screenmanager import ScreenManager
from kivy.clock import Clock
from kivy.core.text import LabelBase
from kivymd.uix.label import MDLabel
from kivymd.uix.label import MDLabel
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import StringProperty,NumericProperty
from kivymd.uix.textfield import *
import lk_k
Window.keyboard_anim_args = {"d":.2,"t":"in_out_quart"}
Window.softinput_mode = ""

class Command(MDLabel):
    text = StringProperty()
    size_hint_x = NumericProperty()
    halign = StringProperty()
    font_size=26

class Response(MDLabel):
    text = StringProperty()
    size_hint_x = NumericProperty()
    halign = StringProperty()
    font_size=26
   

class main(MDApp):

  

    def change_screen(self, name):
        screen_manager.current = name

    def build(self):
        global screen_manager
        screen_manager = ScreenManager()
        screen_manager.add_widget(Builder.load_file("Chats.kv"))

        return screen_manager




    def response(self, *args):
        q=lk_k.get_response(message)
        if len(q)<6:
            s=.22
            h="center"
        elif len(q)<11:
            s=.32
            h="center"

        elif len(q) < 16:
            s = .45
            h = "center"
        elif len(q) < 21:
            s = .58
            h = "center"
        elif len(q) < 26:
            s = .71
            h = "center"
        else:
            s = .77
            h = "center"

            
        screen_manager.get_screen('chats').chat_list.add_widget(Response(text=q, size_hint_x=s,halign=h))

    def send(self):
        global message, size, halign
        if screen_manager.get_screen('chats').text_input != "":
            message = screen_manager.get_screen('chats').text_input.text

            if len(message)<6:
                size=.22
                halign="center"
            elif len(message)<11:
                size=.32
                halign="center"

            elif len(message) < 16:
                size = .45
                halign = "center"
            elif len(message) < 21:
                size = .58
                halign = "center"
            elif len(message) < 26:
                size = .71
                halign = "center"
            else:
                size = .77
                halign = "left"
            screen_manager.get_screen('chats').chat_list.add_widget(Command(text=message,size_hint_x=size,halign=halign))
            Clock.schedule_once(response, 1)
            screen_manager.get_screen('chats').text_input.text = ""
    global counter
    counter = 0
    def clear_image(self):
        global counter
         
        if counter==0:
            self.ids.img2.source ='LOGO.png'
            self.ids.img2.reload() 
            counter += 1
        elif counter==1:
            self.ids.img2.source ='on.png'
            self.ids.img2.reload() 
            counter += 1
            
        elif counter==2:
            self.ids.img2.source ='off.png'
            self.ids.img2.reload() 
            counter += 1
        elif counter==3:
            self.ids.img2.source =''
            self.ids.img2.reload() 
            counter =0
  



if __name__ == "__main__":
   main().run()

My chats.kv file

<Command>
    size_hint_y:None
    pos_hint:{"right": .99}
    height: self.texture_size[1]
    padding: 12,10
    theme_text_color: "Custom"
    text_color:53/255,56/255,60/255,1
    canvas.before:
        Color:
            rgb: (1, 1,1,1)
        RoundedRectangle:
            size:self.width,self.height
            pos:self.pos
            radius:[23,0,23, 23]
<Response>
    size_hint_y:None
    pos_hint:{"x": .01}
    height: self.texture_size[1]
    padding: 12,10
    theme_text_color: "Custom"
    text_color: 53/255,56/255,60/255,1
    canvas.before:
        Color:
            rgb: ( 0,1,1, 1)
        RoundedRectangle:
            size:self.width,self.height
            pos:self.pos
            radius:[0,23,23,23]




MDScreen:
    bot_name: bot_name
    text_input: text_input
    chat_list: chat_list
    name: "chats"

    MDFloatLayout:
       
        canvas :
            Color:
                rgb:1,1,1, 1
            Rectangle:
                id: img2
                source:'q3.png'
                size:self.size
                pos:self.pos
        MDFloatLayout:
            md_bg_color: 0,1,1,1
            size_hint_y:.11
            pos_hint: {"center_y":.96}
            MDLabel:
                id: bot_name
                text:"OLIVIA"
                right_action_items: [["dots-vertical", lambda x: app.callback(x)]]
 
                font_size: "25sp"
                pos_hint: {"center_y": .43}
                halign: "center"

                theme_text_color: "Custom"
                text_color: 53/255,56/255,60/255,1
            MDIconButton:
                icon:"emma.png"
                
                pos_hint:{"center_x":.2,"center_y":.43}
                user_font_size:"15sp"
                theme_text_color:"Custom"
                text_color:53/255,56/255,60/255,1
                md_bg_color: 127/255,1, 212/255, 1
            MDIconButton:
                icon:"video-outline"           
                pos_hint:{"center_x":.80,"center_y":.43}
                user_font_size:"31sp"        
                theme_text_color: "Custom"
                text_color:53/255,56/255,60/255,1       
            MDIconButton:

                text:"M"           
                pos_hint:{"center_x":.90,"center_y":.43}
                user_font_size:"31sp"        
                theme_text_color: "Custom"
                text_color:53/255,56/255,60/255,1   
                on_release: app.clear_image()   
 
        ScrollView:
            size_hint_y:.78
            background_color:1,1,1,1
            pos_hint:{"x":0,"y":.116}
            do_scroll_x:False
            do_scroll_y:True
            BoxLayout:
                id:chat_list
                orientation:'vertical'
                size:(root.width,root.height)
                height:self.minimum_height
                size_hint:None, None
                pos_hint:{"top": 1}
                cols:1
                spacing:3

                        
            
        MDFloatLayout:
            size_hint_y:.08
            md_bg_color:0,1,1,1
            MDFloatLayout:
                size_hint:.8, .75
                pos_hint:{"center_x":.43,"center_y":.5}
                md_bg_color:0,1,1,1
                canvas:
                    Color:
                        rgb:1,1,1, 1
                    RoundedRectangle:
                        size:self.size
                        pos:self.pos
                        radius:[23, 23, 23, 23]

                
                TextInput:
                    id:text_input
                    hint_text:"Type your message"
                    size_hint:1, None
                    pos_hint:{"center_x":.5,"center_y":.5}
                    multiline:False
                    font_size:"18sp"
                    height:self.minimum_height
                    cursor_color:1, 170/255, 23/255, 1
                    cursor_width:"2sp"
                    foreground_color:53/255,56/255,60/255,1
                    background_color:0,0,0,0
                    padding:30
                    
              
            MDIconButton:
                icon:"send-outline"
                pos_hint:{"center_x":.91,"center_y":.5}
                user_font_size:"23sp"
                theme_text_color:"Custom"
                text_color:1,1,1,1
                md_bg_color: 0,1,1,1
                on_press:app.send()

Any help would be great



Solution 1:[1]

You cannot assign an id to a canvas instruction, but you can assign one to the widget that contains the canvas instruction. And, if you want to change the canvas instruct using python, it will be easier if the canvas instructions are defined in python rather than in kv. In order to do that, you can define an extension of MDFloatLayout that does the canvas instructions:

class MyMDFloatLayout(MDFloatLayout):
    def __init__(self, **kwargs):
        super(MyMDFloatLayout, self).__init__(**kwargs)
        with self.canvas:
            Color(1, 1, 1, 1)  # set the colour

            # Setting the size, position, and source of canvas
            self.rect = Rectangle(pos=self.pos,
                                  size=self.size,
                                  source='q3.png')

        # Update the canvas when the position/size changes
        self.bind(pos=self.update_rect,
                  size=self.update_rect)

    # update function which makes the canvas adjustable.
    def update_rect(self, *args):
        self.rect.pos = self.pos
        self.rect.size = self.size

Then you can use this widget in your kv file in place of the MDFloatLayout that contains the canvas that we want to adjust:

MyMDFloatLayout:
    id: img2
   
    # canvas :
    #     Color:
    #         rgb:1,1,1, 1
    #     Rectangle:
    #         id: img2
    #         source:'q3.png'
    #         size:self.size
    #         pos:self.pos

Note that these canvas instructions in the kv are no longer required

Then, in your python code:

def clear_image(self):
    global counter

    if counter == 0:
        widget = self.root.get_screen('chats').ids.img2
        widget.rect.source = 'LOGO.png'
        # self.ids.img2.source = 'LOGO.png'
        # self.ids.img2.reload()
        counter += 1

and similar for the other counter values.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 John Anderson