Alex
Alex

Reputation: 67

Change widget background color in Kivy

As the title suggests, I want to be able to change the background color of a gridlayout widget in Kivy

I'm using the following code:

from kivy.utils import get_color_from_hex
from kivy.graphics import Color, Rectangle
from kivy.lang import Builder
from kivy.base import runTouchApp
from kivy.uix.gridlayout import GridLayout


Builder.load_string('''
#:import utils kivy.utils
<BlueGrid>:
    GridLayout:
        canvas.before:
            Color:
                rgb: utils.get_color_from_hex("#39B3F2")
            Rectangle:
                size: self.size
                pos: self.pos
        rows: 1
        cols: 2
        pos_hint: {"top": 1, "left": 1}
        size_hint: 1, 1
        Label:
            text: "First Label"
            id: Label_1
        Label:
            text: "Second Label"
            id: Label_2
''')

class BlueGrid(GridLayout):
    pass

runTouchApp(BlueGrid())

I am expecting a blue gridlayout where each column is completing filled by one label. Instead, I get the output below, where everything is concentrated in the bottom left corner: output gridlayout

I have also tried running the "BlueGrid" class without the runTouchapp, with the same result:

class MyApp(App):
    def build(self):
        return BlueGrid()


if __name__ == "__main__":
    MyApp().run()
    print(kivy.__file__)

What am I missing? Why are the two labels and the Rectangle in the Gridlayout all positioned on top of each other?

Upvotes: 0

Views: 5482

Answers (2)

John Anderson
John Anderson

Reputation: 38837

Did you notice the warning:

[WARNING] <__main__.BlueGrid object at 0x7f2d2a414e18> have no cols or rows set, layout is not triggered.

That is because you have defined BlueGrid as an extension of GridLayout, but did not specify cols or rows in your kv for BlueGrid. You can correct that by just adding a cols specification:

<BlueGrid>:
    cols: 1

But because BlueGrid is a GridLayout, do you really want another GridLayout inside it? Perhaps a better solution is:

#:import utils kivy.utils
<BlueGrid>:
    canvas.before:
        Color:
            rgb: utils.get_color_from_hex("#39B3F2")
        Rectangle:
            size: self.size
            pos: self.pos
    rows: 1
    cols: 2
    pos_hint: {"top": 1, "left": 1}
    size_hint: 1, 1
    Label:
        text: "First Label"
        id: Label_1
    Label:
        text: "Second Label"
        id: Label_2

Upvotes: 1

noEmbryo
noEmbryo

Reputation: 2231

The reason for this, is that the default size of the GridLayout is not enough to display both of the labels.
Also the root layout of your app might be better to be a FloatLayout or a BoxLayout, so it can occupy all of the window.

So one solution would be to set class BlueGrid(FloatLayout):

Another solution would be to keep it as a GridLayout but set its child GridLayout to a bigger size like this:

<BlueGrid>:
    GridLayout:
        size_hint: None, 1
        width: 300

Upvotes: 0

Related Questions