I.Bozcan
I.Bozcan

Reputation: 45

How to change label background color dynamically in Kivy

I try to make a simple ToDoList program.There are add, remove and do it buttons. But I have some bugs about labels color. When I click "DO IT" button label color change in scrollview but when I click remove button when some of them done, colored labels change. I did using canvas. How can I fix this problem?

class Home(Screen):

    def __init__(self,**kwargs):
        super(Home,self).__init__(**kwargs)

    def addWidget(self):
        task_input = self.ids.task_input.text
        newListItem = EachTask(text=task_input , 
        id=str((len(self.ids.add_field.children))) )
        print(newListItem.id)
        self.ids.add_field.add_widget(newListItem)
class EachTask(BoxLayout):
    def __init__(self, text= "", **kwargs):
        super(EachTask,self).__init__(**kwargs)
        self.ids.label.text = text

    def Do_Task(self,instance):
        child = instance.parent.parent
        with self.canvas.before:
            Color(.5,1,.2,1, mode='rgba')
            Rectangle(pos=child.ids.label.pos, size=child.ids.label.size)

kv_file

<FlatButton@ButtonBehavior+Label>:
    font_size: 15


<Home>:
    BoxLayout:
        id: home
        orientation: "vertical"
        spacing: 5
        #space_x: self.size[0]/2
        canvas.before:
            Color:
                rgba: (1,1,1,1)
            Rectangle:
                size: self.size
                pos: self.pos

    ##########HEADER#######
        BoxLayout:
            id: header
            size_hint_y: None
            height: 50
            canvas.before:
                Color:
                    rgba: (.85,.7,.2,1)
                Rectangle:
                    size: self.size
                    pos: self.pos
            Label:
                text: "TO DO LIST"
                font_size: "20sp"
                bold: True
                size_hint_x: .9
            FlatButton:
                text: "Back"
                size_hint_x: .1
    ####################################
        ScrollView:
            canvas.before:
                Color:
                    rgba: (1,1,.2,.2)
                Rectangle:
                    size: self.size
                    pos: self.pos
            BoxLayout:
                id: add_field
                size_hint_y: None
                height: self.minimum_height
                orientation: 'vertical'
                spacing: 2   #Spaces between childs
    #####################################################
        BoxLayout:
            id: input_field
            size_hint_y: None
            height: 80
            TextInput:
                id: task_input
                focus: True
                size_hint_x: .9
                multiline: False
            Button:
                font_size: "40sp"
                size_hint_x: .1
                text: "+"
                on_release: root.addWidget()
                id: button1
                color: 1,0.5,0.5,1
#######################################################
<EachTask>:
    size_hint_y: None
    height: 50
    id: each_task
    BoxLayout:
        Label:
            size_hint_x: .8
            id: label
            canvas.before:
                Color:
                    rgba: (1,.2,.2,.2)
                Rectangle:
                    size: self.size
                    pos: self.pos
        Button:
            size_hint_x: .1
            text: "X"
            on_release: app.root.ids.add_field.remove_widget(root)
        Button:
            size_hint_x: .1
            text: "DO IT"
            on_release: root.Do_Task(self)

Upvotes: 1

Views: 4198

Answers (1)

ikolim
ikolim

Reputation: 16001

The following enhancements are required to the kv and py files to solve the problem.

Method 1 - Kivy automatically created & added an ObjectProperty, rgba

Kivy automatically created & added an ObjectProperty

If the widget doesn’t have a property with the given name, an ObjectProperty will be automatically created and added to the widget.

kv file

  1. Add a class attribute, rgba and initialize it to default colour, (1, .2, .2, .2) to class rule, <EachTask>:
  2. Replace label's colour to root.rgba

Snippets - kv file

<EachTask>:
    rgba: (1,.2,.2,.2)    # Kivy auto created & added ObjectProperty, "rgba"
    ...
    BoxLayout:
        Label:
            size_hint_x: .8
            id: label
            canvas.before:
                Color:
                    rgba: root.rgba
                ...

py file

  1. Remove all the codes in method Do_Task()
  2. Add self.rgba = [.5, 1, .2, 1] whereby self refers to the current widget i.e. EachTask object.

Snippets - py file

def Do_Task(self, instance):
    self.rgba = [.5, 1, .2, 1]

Method 2 - Explicitly declaring rgba

kv file

  1. Replace rgba: (1,.2,.2,.2) with root.rgba

Snippets - kv file

<EachTask>:
    ...
    BoxLayout:
        Label:
            size_hint_x: .8
            id: label
            canvas.before:
                Color:
                    rgba: root.rgba
                ...

py file

  1. Add import statement, from kivy.properties import ListProperty
  2. Declare class attribute, rgba of ListProperty type and initilaize it to default colour, [1, .2, .2, .2] in class EachTask()
  3. Remove all the codes in method Do_Task()
  4. Add self.rgba = [.5, 1, .2, 1] whereby self refers to the current widget i.e. EachTask object.

Snippets - py file

from kivy.properties import ListProperty
...
class EachTask(BoxLayout):
    rgba = ListProperty([1, .2, .2, .2])
    ...
    def Do_Task(self, instance):
        self.rgba = [.5, 1, .2, 1]

Upvotes: 3

Related Questions