I am trying to develop an email application in Kivy, basically just as an exercise to learn the in's and out's of the framework... I am trying to create the initial window and have reached a bit of a stumbling block! The idea is that it will simply display a list of emails in the inbox, much like any basic email app on a mobile device.
The problem I'm having is that I can't figure out how to get the text of each list item (which is a just a button) to align properly. Using "halign='left'" in my button will make the text align left, but only relative to each button; it's still centered within each button.
My actual app is a bit large to post, so this is a quick and dirty example I made from a stock Kivy example. (I realize this code isn't perfect... like I said quick and dirty for examples sake... it does work though!) So as you can see, the two rows of text on each button align with each other, but they don't all align overall. Can anyone suggest what I would do to make all the text align at, say, 10px from the left of each button? I did find one relative sounding item on StackOverflow, but it didn't really answer the question for example, it seemed to deal more with using images on buttons. I am new to Kivy, but I've read through the tutorials and documentation, as well as searched Google extensively - so any help would be greatly appreciated!
import kivy
kivy.require('1.0.8')
from kivy.app import App
from kivy.core.window import Window
from kivy.uix.button import Button
from kivy.uix.scrollview import ScrollView
from kivy.uix.gridlayout import GridLayout
import random
class ScrollViewApp(App):
def build(self):
# create a default grid layout with custom width/height
layout = GridLayout(cols=1, spacing=10, size_hint=(None, None),
width=Window.width)
# when we add children to the grid layout, its size doesn't change at
# all. we need to ensure that the height will be the minimum required to
# contain all the childs. (otherwise, we'll child outside the bounding
# box of the childs)
layout.bind(minimum_height=layout.setter('height'))
# add button into that grid
for i in range(30):
btn = Button(text=str(i * random.random()) + '\n' + str(i * random.random()),
size=(300, 40),
size_hint=(None, None),
halign='left')
layout.add_widget(btn)
# create a scroll view, with a size < size of the grid
root = ScrollView(size_hint=(None, None))
root.size = (Window.width, Window.height)
root.center = Window.center
root.add_widget(layout)
return root
if __name__ == '__main__':
ScrollViewApp().run()
The documentation of Button starts with "A Button is a Label". Even for Widgets that don't mention their lineage explicitly, you should take a note of the second line in the API doc of the Widget in question. In this case "Bases: kivy.uix.label.Label".
This establishes that the button inherits from a Label. (I am explicitly mentioning this because this part of looking at the base Class's inherited properties sometimes is not intuitive for everyone).
If you look at the Docs for label, specifically the halign
property, it asks you to utilize text_size
to achieve proper text alignment. What this means is the text is aligned inside a bounding box that is set by the text_size
property. This property can be set to be:
a) The size of the Widget. text_size: self.size
b) Less than the size of the size of the widget (what you are looking for) text_size: self.width - dp(10), self.height - dp(10)
c) Unconstrained on one of the sides text_size: self.width, None
d) or both text_size: None, None
e) or constrained to a different Widget text_size: other_button.size
The reason for using text_size
is to give more control to the user.
You should also look at the textalign example