python kivy add text inside rectangle

kivy, linux, python

Solution

Use `Label` with custom background color then place it inside your layout. For example:

from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ListProperty
from kivy.app import App
from kivy.lang import Builder

from random import random

kv = '''
<ColoredLabel>:
    background_color:
    canvas.before:
        Color:
            rgba: self.background_color
        Rectangle:
            pos: self.pos
            size: self.size
'''

Builder.load_string(kv)

class ColoredLabel(Label):
    background_color = ListProperty((0, 0, 0, 1))

class TestApp(App):
    def build(self):
        layout = BoxLayout(size_hint=(1, None), height=50)
        for label in ('a', 'b', 'c', 'd'):
            label = ColoredLabel(text=label, background_color=(random(), random(), random(), 1))
            layout.add_widget(label)

        return layout

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

update

Fixing issue from OP:

import kivy
from kivy.app import App
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.video import Video
from kivy.uix.relativelayout import RelativeLayout
from kivy.graphics import *
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from random import random
from kivy.properties import ListProperty


kv = '''
<ColoredLabel>:
    size: (100,100)
    pos: (10,10) # no effect
    background_color:
    canvas.before:
        Color:
            rgba: self.background_color
        Rectangle:
            pos: self.pos
            size: self.size
    '''

Builder.load_string(kv)

class ColoredLabel(Label):
    background_color = ListProperty((0,0,0,1))

class MyApp(App):
    def build(self):
        f = AnchorLayout()
        g = GridLayout(cols=2, rows=2)
        layout = BoxLayout(size_hint=(1, None), height=50)
#        v = Video(source='driver.mp4', state='play', options={'eos':'loop'})
        l1 = Label(text="jenkins", font_size=32)
        l2 = Label(text="git", font_size=32)
#        f.add_widget(v)

        label = ColoredLabel(text="Hello World!", size_hint=(None, None), background_color=(random(), random(), random(), 1))
        g.add_widget(label)

        f.add_widget(g)

        return f

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

Notice that `Rectange` of `ColoredLabel` needs to have `pos: self.pos` and `size: self.size` to draw in place where the label actually is. That's why I changed size of Label itself in the level above. Canvas size is binded to it. As for position, it's controlled by the Layout in which `ColoredLabel` is placed, so changing it from `ColoredLabel` class doesn't change much. Compare it with `FloatLayout`:

import kivy
from kivy.app import App
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.video import Video
from kivy.uix.relativelayout import RelativeLayout
from kivy.graphics import *
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from random import random
from kivy.properties import ListProperty

from kivy.uix.floatlayout import FloatLayout


kv = '''
<ColoredLabel>:
    size: (150, 200)
    pos: (50, 150)
    background_color:
    canvas.before:
        Color:
            rgba: self.background_color
        Rectangle:
            pos: self.pos
            size: self.size
    '''

Builder.load_string(kv)

class ColoredLabel(Label):
    background_color = ListProperty((0,0,0,1))

class MyApp(App):
    def build(self):
        f = FloatLayout()
        label = ColoredLabel(text="Hello World!", size_hint=(None, None), background_color=(random(), random(), random(), 1))
        f.add_widget(label)

        return f

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

In this case changing pos inside of `ColoredLabel` actually has an effect.

Problem

How can I add text inside a rectangle? I am using the code below and added a label inside the canvas hoping that it will display inside the rectangle. ``` import kivy from kivy.app import App from kivy.uix.anchorlayout import AnchorLayout from kivy.uix.gridlayout import GridLayout from kivy.uix.label import Label from kivy.uix.video import Video from kivy.uix.relativelayout import RelativeLayout from kivy.graphics import * class MyApp(App): def build(self): r = AnchorLayout() f = RelativeLayout() g = GridLayout(cols=3, rows=5) v = Video(source='driver.mp4', state='play', options={'eos':'loop'}) l1 = Label(text="jenkins", font_size=32) l2 = Label(text="git", font_size=32) f.add_widget(v) f.add_widget(g) g.add_widget(l1) g.add_widget(l2) with g.canvas: Color(.4, .1, .1) Rectangle(pos=(100,10), size=(100,100)) Label(text="KSHK") return f if __name__ == "__main__": MyApp().run() ``` update: this does not align the text in the center of ColoredLabel ``` import kivy from kivy.app import App from kivy.uix.anchorlayout import AnchorLayout from kivy.uix.gridlayout import GridLayout from kivy.uix.label import Label from kivy.uix.video import Video from kivy.uix.relativelayout import RelativeLayout from kivy.graphics import * from kivy.lang import Builder from kivy.uix.boxlayout import BoxLayout from random import random from kivy.properties import ListProperty kv = ''' <ColoredLabel>: background_color: canvas.before: Color: rgba: self.background_color Rectangle: pos: (10,10) size: (100,100) ''' Builder.load_string(kv) class ColoredLabel(Label): background_color = ListProperty((0,0,0,1)) class MyApp(App): def build(self): f = AnchorLayout() g = GridLayout(cols=2, rows=2) layout = BoxLayout(size_hint=(1, None), height=50) v = Video(source='driver.mp4', state='play', options={'eos':'loop'}) l1 = Label(text="jenkins", font_size=32) l2 = Label(text="git", font_size=32) f.add_widget(v) label = ColoredLabel(text="Hello World!", background_color=(random(), random(), random(), 1)) g.add_widget(label) f.add_widget(g) return f if __name__ == "__main__": MyApp().run() ```

Original source