The Goal
I have a widget class with a property c_description
. I need to be able to create and add a label (or some other type of widget) to this widget that inherits c_description
as text. And changes to c_description
propagate to the label's text. I need to be able to run this creation/addition of this label with a function.
I basically need to do exactly what this other question is asking about.
What I did and what problems I ran into
I formatted this label class StretchingLabel
stretch to fit its contents. I to I have a script in kivy that shows how I want it to work.
The end result should look like this.
This is the other script in which I dynamically create and add a new widget after unsuccessfully binding its text
property to c_description
.
If I run that I get a result that looks like this.
The text of the label is "" rather than the contents of c_description
, so that's one problem.
But if I removing the property binding statement and change c_label = StretchingLabel()
to c_label = StretchingLabel(pos=self.pos, width=self.width, text=self.c_description)
we should be able to at least see what a successful property binding looks like.
When I do that, the result looks like this.
This is not what I want. I want it to look like the 1st picture.
My Code
from kivy.app import App
from kivy.lang import Builder
from kivy.clock import Clock
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty
from kivy.uix.textinput import TextInput
Builder.load_string('''
<StretchingLabel>:
size_hint_y: None
text_size: self.width, None
height: self.texture_size[1]
group: 'test'
canvas.before:
Color:
rgba: .7, .7, .7, 1
Rectangle:
pos: self.pos
size: self.size
<MyLabelFrame>:
id: xLabel
<ContainerBox>:
orientation: 'horizontal'
Button:
text: 'h1'
group: 'test'
BoxLayout:
orientation: 'vertical'
size: root.size
pos: root.pos
Label:
text: 'Description'
size_hint_y: None
height: 30
bold: True
MyLabelFrame:
Label:
''')
class StretchingLabel(Label):
def __init__(self, **kwargs):
super(StretchingLabel, self).__init__(**kwargs)
#This is for debugging
Clock.schedule_once(lambda dt: print("StretchingLabel.init(): ", self.text), timeout=0.01)
def on_double_click(self, instance, p_ignoreme):
#This is also for debugging
print("StretchingLabel.on_double_click():", self.text)
class MyLabelFrame(Widget):
c_description = StringProperty(
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. \n\nProin vitae turpis ornare urna elementum pharetra non et tortor. Curabitur semper mattis viverra. \nPellentesque et lobortis purus, eu ultricies est. Nulla varius ac dolor quis mattis. Pellentesque vel accumsan tellus. Donec a nunc urna. Nulla convallis dignissim leo, tempor sagittis orci sollicitudin aliquet. Duis efficitur ex vel auctor ultricies. Etiam feugiat hendrerit mauris suscipit gravida. Quisque lobortis vitae ligula eget tristique. Nullam a nulla id enim finibus elementum eu sit amet elit.')
def __init__(self, **kwargs):
super(MyLabelFrame, self).__init__(**kwargs)
Clock.schedule_once(lambda dt: self.makeLabel(), timeout=0.01)
def makeLabel(self):
c_label = StretchingLabel()
#HERE! This vvv does not seem to work for some reason.
self.bind(pos=c_label.setter('pos'), width=c_label.setter('width'), c_description=c_label.setter('text'))
#This vvv didn't work either.
#c_label.bind(pos=self.setter('pos'), width=self.setter('width'), text=self.setter('c_description'))
self.add_widget(c_label)
class ContainerBox(BoxLayout):
def __init__(self, **kwargs):
super(ContainerBox, self).__init__(**kwargs)
class Nested2App(App):
def build(self):
return ContainerBox()
if __name__ == '__main__':
Nested2App().run()
My questions to you
- Why does
self.bind(c_description=c_label.setter('text'))
not work? The label is being created, but it's not getting the text fromc_description
. What am I doing wrong? - Why is the formatting wrong on the created label? I passed the same properties in the kv code that I did in
makeLabel()
. And I need to be able to do this properly with themakeLabel()
function.
Note
I saw another question here that had the exact same problem I did (without the formatting issue), but for some reason the answer didn't work for me.