bind on_texture for dynamically resizing font in a label

2,164 views
Skip to first unread message

com...@motaj.com

unread,
Jan 29, 2013, 8:37:55 PM1/29/13
to kivy-...@googlegroups.com
I've got a label whose text changes dynamically on button pressess. At some point in time the text texture is larger than the lable size and hence the remaining text is not displayed. I first tried shorten thinking it would do the trick, instead it only adds '...' at the end and I obviously misunderstood its usage. Here's a snippet of my code

.kv:

t2_wid: TI2        
       
Label:
            canvas
.before:
               
Color:
                    rgb
: 255, 250, 250
               
Rectangle:
                    pos
: self.pos
                    size
: self.size
            id
: TI2
            color
: 0,0,0,1
            size_hint
: 1, 0.1  
            font_size
: self.height/2
            on_text
: root.do_on_text()
            font_name
: 'DejaVuSans.ttf'
            text_size
: TI2.width, None
            on_texture
: root.change_font_size()



So I've bound on_texture to a function change_font_size()and what this is supposed to accomplish is that as soon as the text size goes beyond the actual label size (width), it needs to reduce the font size to accommodate all the text within the visible part of the label. I've tried something like this, but it doesn't seem to work:

In .py:

t2_wid = ObjectProperty() #this is the label widget from above

def change_font_size(self):
   
#a function to dynamically reduce font size to fit the text within the label
   
if self.t2_wid.text_size == self.t2_wid.width: #this is the part which I think has issues in it. I'm not sure if I look for changes in text_size or texture_size
       
self.t2_wid.font_size =self.t2_wid.font_size/2

Gabriel Pettier

unread,
Jan 30, 2013, 7:00:23 AM1/30/13
to kivy-...@googlegroups.com
Hi

text_size is the limits you give to your text rendering, here you
limited width to TI2.width, so when the text is larger than that, a
carriage return will be introduced to split the text across multiple
lines, of course, then your text can still overflow on heigh, and be
masked by surrounding elements. In this case, it can make sense to
reduce the font_size, if you can't make your UI more flexible (giving
more place to the label). You did an error on that, as you intuited,
though, as in your callback, you check text_size (which won't change,
it's the limations you gave), instead of texture_size (which is the size
of the rendered text), also, you probably want to compare
texture_size[1] to self.t2_wid.heigh. If it's superior, then you can,
for example remove one point to the font_size, but it would be more
clever to bind the callback to texture or texture_size, i think, so the
callback is called continuously until the text fit in the place.

Are things more clear?
> --
> You received this message because you are subscribed to the Google Groups "Kivy users support" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to kivy-users+...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

com...@motaj.com

unread,
Jan 31, 2013, 7:59:22 PM1/31/13
to kivy-...@googlegroups.com
Thanks alot for the reply and the ideas, I got it to work but with by making sacrifice on the text alignment. To make it work I had to remove the text_size binding so now the text is always rendered by centre alignment rather than left alignment (which I'd prefer). Below is the modified code

.kv:

t2_wid: TI2        
        
Label:
            canvas
.before:
                
Color:
                    rgb
: 255, 250, 250
                
Rectangle:
                    pos
: self.pos
                    size
: self.size
            id
: TI2
            color
: 0,0,0,1
            size_hint
: 1, 0.1
  
            font_size
: TI2.height/2
            on_text
: root.do_on_text()
            font_name
: 'DejaVuSans.ttf'
            on_texture
: root.change_font_size()





In .py: I had to look for changes in self.t2_wid.texture_size[0] for width and self.t2_wid.texture_size[1] for height (as shown below)

t2_wid = ObjectProperty() #this is the label widget from above

def change_font_size(self):
    
#a function to dynamically reduce font size to fit the text within the label

    
if self.t2_wid.texture_size[0] >= self.t2_wid.width or self.t2_wid.texture_size[1] >= self.t2_wid.height:
        self.t2_wid.font_size -= 1

Any ideas on how I could get past centre alignment?
Reply all
Reply to author
Forward
0 new messages