Search code examples
pythonpython-3.xkivykivy-language

Kivy sizing label inside RecycleView


enter image description hereI would like my label to have exactly the height it needs to display its text. It is inside a RecycleView. I think my code should work outside an RecycleView.

How can I make the Label big enough so that its content can easily be read? In the same way as it already works for CodeInput and TextInput.

from kivy.base import runTouchApp
from kivy.lang import Builder
from kivy.uix.recycleview import RecycleView
from kivy.uix.label import Label
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
from kivy.properties import StringProperty


Builder.load_string('''
<RV>:
    viewclass: 'SnippetView'
    RecycleBoxLayout:
        default_size: None, dp(56)
        default_size_hint: 1, None
        size_hint_y: None
        height: self.minimum_height
        orientation: 'vertical'
        spacing: 10

<SnippetView>:
    canvas.before:
        Color:
            rgb: (255,0,0)
        Rectangle:
            pos: self.pos
            size: self.size
    orientation: 'vertical'

    Label:
        text: root.heading
        text_size: root.width, None
        size: self.texture_size
    TextInput:
        text: root.dscrpt
        size_hint_y: None
        height: self.minimum_height
    CodeInput:
        text: root.code
        size_hint_y: None
        height: self.minimum_height

''')

class SnippetView(BoxLayout):
    heading = StringProperty()
    dscrpt = StringProperty()
    code = StringProperty()


class RV(RecycleView):
    def __init__(self, **kwargs):
        super(RV, self).__init__(**kwargs)
        self.data = [{'heading': str(x),'dscrpt': str(x),'code': str(x)} for x in range(100)]

rv = RV()
runTouchApp(rv)

I am also thankful for any comments regarding RecycleView in general since I am using it for the first time.


Solution

  • You must bind a method to update the height of your SnippetView when the value of the label change because you have fixed it in the rule of your RV. Try this:

    ...
    
    Builder.load_string('''
    
    ...
    
    <SnippetView>:
        canvas.before:
            Color:
                rgb: (255,0,0)
            Rectangle:
                pos: self.pos
                size: self.size
        orientation: 'vertical'
    
        Label:
            id: l
            text: root.heading
            text_size: root.width, None
            size: self.texture_size
        TextInput:
            id: ti
            text: root.dscrpt
            size_hint_y: None
            height: self.minimum_height
        CodeInput:
            id: ci
            text: root.code
            size_hint_y: None
            height: self.minimum_height
    
    ''')
    
    class SnippetView(BoxLayout):
        heading = StringProperty()
        dscrpt = StringProperty()
        code = StringProperty()
    
        def __init__(self, **kwargs):
            super(SnippetView, self).__init__(**kwargs)
            self.ids.l.bind(height=self.update)
    
        def update(self, *args):
            self.height = self.ids.l.texture_size[1] + self.ids.ti.height + self.ids.ci.height
    
    ...