Home > other >  Kivy: Create a list of coloured labels using build() method
Kivy: Create a list of coloured labels using build() method

Time:01-08

I want to create a list of coloured labels. The thing is that I could do it with the kv file, but I need to do it through the build() method. So I tried replicate what I have done, but it does not work. And I can't understand why.

This is what I've coded

from kivy.app import App
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.graphics import *

class RL(RelativeLayout): # Creates the background colour for each label
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        with self.canvas:
            Color(.7, 0, .5, 1)
            Rectangle(size_hint=self.size)

class MainMenu(BoxLayout):
    
    N_LBLS = 8
    labels_text = []
    RL_list = []

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        button = Button(text='do something')
        button.bind(on_release=self.change_text)
        box = BoxLayout(orientation='vertical', padding= 10, spacing = 15)
        for i in range(0, self.N_LBLS):
            self.RL_list.append(RL())
            self.labels_text.append(Label(text=f'{i}º label', size_hint=self.size))
            self.RL_list[i].add_widget(self.labels_text[i])
            box.add_widget(self.RL_list[i])
        self.add_widget(button)
        self.add_widget(box)

    def change_text(self, instance):
        for lbl in self.labels_text:
            if lbl.text[0] == '5':
                lbl.text = 'Text changed'

class MainApp(App):
    def build(self):
        return MainMenu()

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

It's supposed to make a button to the left, and a list of 8 coloured labels to the right.

CodePudding user response:

The problem is that you are setting size_hint=self.size in each Label. The self.size is the size of the MainMenu, which is [100,100] when that code is executed. Note that size_hint is a multiplier that is applied to the parents size to calculate the widgets size. So a size_hint of [100,100] makes each Label 100 times bigger than the MainMenu. So your code is working, but the Labels are so large that the text is off the screen. Start by just removing size_hint=self.size.

And, to set a background color on a Label, you can just use the canvas of that Label, rather than some container. Here is a version of your code that does that:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout


class ColorLabel(Label):
    pass


Builder.load_string('''
<ColorLabel>:
    bg_color: [.7, 0, .5, 1]
    canvas.before:
        Color:
            rgba: self.bg_color
        Rectangle:
            pos: self.pos
            size: self.size
''')


class MainMenu(BoxLayout):
    N_LBLS = 8
    labels_text = []

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        button = Button(text='do something')
        button.bind(on_release=self.change_text)
        box = BoxLayout(orientation='vertical', padding=10, spacing=15)
        for i in range(0, self.N_LBLS):
            self.labels_text.append(ColorLabel(text=f'{i}º label'))
            box.add_widget(self.labels_text[i])
        self.add_widget(button)
        self.add_widget(box)

    def change_text(self, instance):
        for lbl in self.labels_text:
            if lbl.text[0] == '5':
                lbl.text = 'Text changed'
                lbl.bg_color = [0, 1, 0, 1]


class MainApp(App):
    def build(self):
        return MainMenu()


if __name__ == '__main__':
    MainApp().run()
  •  Tags:  
  • Related