Search code examples
pythonpython-3.xkivykivy-language

How to create a python kivy label that's color is stored in a variable that can be accessed by other kivy widget classes and updated during runtime


I have three .kv files that are each for a screen in my app, one is the screen manager and the other two are the actual screens. I need to store the color attribute of a label in one of my screens to a variable in my main app class, this way I can update that variable from my other screen and change the color of the Label in the other screen.

main.py

from utils.imports import *
Window.size = (400, 700)


class ScreenM(ScreenManager):
    pass

class Calc(Screen):
# there are a bunch of functions in here to do calculations but i felt there wasn't a need to include them

class MenuScreen(Screen):
    pass

class Main(App):
    color = rgba("#FFF000")
    def update_color(self):
        self.color = rgba("#000000")
    def build(self):
        return ScreenM()


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

main.kv

#:include calc.kv
#:include menu_screen.kv
<ScreenM>:
    Calc:
    MenuScreen:

calc.kv

#:include utils/custom_widgets.kv
<Calc>:
    name: "calc"
    #:set sp dp("5")
    AnchorLayout:
        padding: sp
# Text background Color
        LabelB:
            bcolor: 1,1,1,1

        BoxLayout:
            orientation: "vertical"
            BoxLayout:
# Text Panel
                AnchorLayout:
                    size_hint: 1, 1
                    BoxLayout:
                        padding: sp
                        orientation: "vertical"
                        AnchorLayout:
                            anchor_y: "top"
                            size_hint: .15, .15
                            LabelB:
                                bcolor: 1, 1, 1, 1
                            ButtonI:
                                source: "resources/images/square_menu_icon.resized.png"
                            Button:
                                on_release: app.root.current = "menu"
                                background_normal: "resources/images/empty.png"
                                background_down: "resources/images/gray_n.jpeg"
# The Label i want to chage the color of
#############
#############

                        Label:
                            text: root.d1
                            font_size: 50 if self.text == '' else min(48,max(30/len(self.text) * 15, 15))
                            color: app.color
#############
#############
#############
# History Panel
                AnchorLayout:
                    padding: sp
                    size_hint: .335, 1
# History Background Color
                    LabelB:
                        bcolor: 1, 1, 1, 1
                    ScrollView:
                        start_pos: 'bottom'
                        padding: 5
                        Label:
                            text: root.history
                            text_size: self.width, None
                            color: 1, 0, 0, 1
                            font_size: 40
                            halign: 'left'
                            valign: 'top'
                            size_hint_y: None
                            height: self.texture_size[1]
# Buttons
            AnchorLayout:
# Buttons Background Color
                LabelB:
                    bcolor: 1, 1, 1, 1
# Main Layout
                BoxLayout:
                    orientation: "vertical"
                    spacing: sp

# Button Row 1
                    BoxLayout:
                        spacing: sp
                        Button:
                            text: "C"
                            on_press: app.update_color()
                            font_size: dp(20)

# i remove the rest of the buttons for simplicity

menu_screen.kv

<MenuScreen>:
    name: "menu"
    Button:
        text: "change color"
        on_press: app.update_color
        on_press: app.root.current = "calc"

When i run this nothing happens to the color, any help would be greatly appreciated.


Solution

  • Just change:

    class Main(App):
        color = rgba("#FFF000")
    

    to:

    class Main(App):
        color = ListProperty(rgba("#FFF000"))
    

    When attributes (like color) are set in kv, they take the value of the variable at the time the kv is evaluated. If you want the widget color to change when the variable changes, the variable must be a Property.