How to have a button text that fit the size of a Button automatically ?

7,373 views
Skip to first unread message

Stephane Martel

unread,
Nov 7, 2018, 3:47:26 AM11/7/18
to Kivy users support


Hi,

I try to have a Kivy app working either on windows ans on android smartphone. In this app for the UI i have two colomns of Buttons. (Look at the screenshot bellow)

On each button the size of the text of the button may be different depending on the size of the text. Secondly the resolution of the screen depends on the platform the kivy app is run. My issue is that on android as the portrait vertical resolution is 2792 pixel each button has a huge vertical size. So a font_size: self.width/2 is not enough on android as the text becomes much to big and large out of the button, and so does not take into account the text size.

How can i do, to have on any plateform the text of the button fit the size of the Button depending on the text lenght, the font and the button size (itself depending of the size of the main window/screen). I also want on windows that if i stretch the window, it dynamically ajusts the buttons size and the text of the button proportionnally (by default the button size is adapted but the text stays at font_size size, and calculating the font_size only with the button width doe not allow to fit correctly because of the text length that is not proportional).

Thank's in advance for your Help

Regards


On the smartphone using Pydroid 3  With a 1440 * 2792 Pixels Resolution :

Screenshot_20181107-092706_Pydroid 3.jpg


On Windows 10 with a 800 * 600 resolution :

Kivi App on Windows10.png


Глеб Самойлов

unread,
Nov 7, 2018, 9:53:03 AM11/7/18
to Kivy users support
Always use sp units for font size:

Button:
   font_size
:'10sp'

And to specify the size of the widget - unit dp:

Button:
   size_hint
: None, None
   size
: dp(80), dp(40)

This ensures the correct display of sizes on all screens.

среда, 7 ноября 2018 г., 10:47:26 UTC+2 пользователь Stephane Martel написал:

ZenCODE

unread,
Nov 7, 2018, 3:43:14 PM11/7/18
to Kivy users support
Or, if you want the text size to scale with the button size...

Button:
   font_size
: 0.75 * self.height

Stephane Martel

unread,
Nov 8, 2018, 3:00:28 AM11/8/18
to Kivy users support
Thank's for your answer, but it still not fit my need, because if i set dp  on the button, the button is not anymore dynamic depending on the screen size (smartphone or desktop), and if i do not set dp, the button is size dynamic, but the text size only adapt his vertical size depending on the button vertical size, but concerning the horizontal size the text begins before the button, and goes after the button on the right of it  (font size 75sp & size: dp(400), dp (100):

Kivi App on Windows10-2.png


On android it is worse :


Screenshot_20181108-085515_Pydroid 3.jpg


The main difficulty for me is to make a dependance between the horizontal size of the widget and the length of the text (Horizontal size of the text), and also integrate teh vertical size proportion that can anyway not be the only proportion factor.


Do you have some other Ideas ?

Stephane Martel

unread,
Nov 8, 2018, 3:04:25 AM11/8/18
to Kivy users support
Thank's for your suggestion, but as i said in my post, doing like this only manage the vertical proportion, and if the text in the button is composed of two or three words, the text will overfill horizontally the button, as it doe not take into account thehorizontal size of the text (only the vertical component of the size)

Do you have any other idea ?

Boca Valentin

unread,
Nov 10, 2018, 3:08:09 AM11/10/18
to kivy-...@googlegroups.com
Maybe the code below will help you. It's just an example, resize window hight / width to see the effects.

from kivy.uix.label import Label
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.core.window import Window

class MainApp(App):

    def build(self):
ecran = FloatLayout()
container = GridLayout()
container.cols = 1
container.pos_hint = { "center_x": 0.5, "center_y": 0.5 }
container.size_hint = ( None, None )
container.spacing = 20
container.width = 200


container.bind( minimum_height = container.setter("height") )
ecran.add_widget( container )


for i in range( 0, 20, 2 ):
buton = Button()
# (padding_x, padding_y), equal padding, horizontal and vertical
buton.padding = (10, 10)
buton.text = "Example " * i
buton.size_hint_y = None
buton.bind( width = lambda s, w: s.setter( "text_size" ) ( s, (w, None) ) )
buton.bind( texture_size = buton.setter("size") )
container.add_widget( buton )

print("\n\n")
print( "Width of the \'ecran\': " + str(ecran.width) )
print( "Window width: " + str(Window.width) )
print( "Window height: " + str(Window.height) )
print("\n\n")
return ecran

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

--
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.
To post to this group, send email to kivy-...@googlegroups.com.
Visit this group at https://groups.google.com/group/kivy-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/3eeb6055-f07c-4e60-8ebe-7f6a1a3dd185%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Stephane Martel

unread,
Nov 13, 2018, 4:50:00 PM11/13/18
to Kivy users support
Hi, many thank's for this idea, but your code allow to create dynamic buttons that adjust themselves to the text size. What i need is the opposite, the text must auto size to fit a button size that is itself dynamicaly determined by the layout, itself depending on the size screen (Pc Screen or Smartphone one).

Regards

Andrew McLeod

unread,
Nov 14, 2018, 4:06:50 AM11/14/18
to kivy-...@googlegroups.com
If you need to have auto-sizing text, then I would try something like:
Pick an arbitrary font size
Let the text be drawn
Get the texture size and see how big it is
Shrink the font size so that it 'should' fit
Check it does fit (and if not, repeat with a fudge factor)

Andrew

Thomas S.

unread,
Nov 14, 2018, 9:53:32 AM11/14/18
to Kivy users support
The following lines will make the text of the button to fit exactly to the size of the button. In other words, the button will act as a wrap-around for the text.

size: self.texture_size
size_hint: None, None

Alternatively, one can add some padding by doing:

width: self.texture_size[0] + dp(5)
height: self.texture_size[1] + dp(5)
size_hint: None, None


Another approach is to make the size of the button depend on the size of the screen as follows:

from kivy.core.window import Window

x = Windows.system_size[0]
y = Windows.system_size[1]

size: .45*x, .20*y  # You have to find a suitable factor that fits your needs here
size_hint: None, None

or use kivy.metrics:

from kivy.metrics import Metrics

screen_dpi = Metrics.dpi
size: .5*screen_dpi, .6*screen_dpi   # You have to find a suitable factor that fits your needs here
size_hint: None, None

Thomas S.

unread,
Nov 14, 2018, 1:01:01 PM11/14/18
to Kivy users support
It is Window not Windows, obviously!!

David Bailey

unread,
Feb 20, 2020, 9:49:03 PM2/20/20
to Kivy users support
How about this:

    Button:
        ...
        font_size: 14
        larger_font: min(14, self.font_size + 1)  # one point larger but not over maximum
        on_texture_size:
            if self.texture_size[0] > self.width: self.font_size -= 1  # reduce font size if too wide
            elif self.texture_size[0] + self.font_size / 2 < self.width: self.font_size = self.larger_font  # increase font size if able

 
Reply all
Reply to author
Forward
0 new messages