Creating an Application in Kivy: Part 2

By | June 19, 2013

This article continues the tutorial we started in Part 1. In the first part, we set up a Kivy project and developed a very basic Kivy application. We also discussed version control to aid in project management. In this part, we’ll be designing an actual user interface for a Jabber client and begin to implement it in the KV language.

Make sure you have completed part 1, or if you want to skip the preliminaries, you can clone the end_part_one tag of the Orkiv git repository and start from there. It’s probably a good idea to name a new branch for your working changes so your master branch doesn’t diverge from my upstream repository. Remember to activate the virtualenv you created in Part 1 (or create one if you’re starting from the git clone.)

Table Of Contents

Here are links to other parts of the tutorial. I’m sorry for the navigation faux pas; blogs are not the best interface for multi-part articles.

  1. Part 1: Introduction to Kivy
  2. Part 2: Creating a form
  3. Part 3: Interacting with widgets and the user
  4. Part 4: Code and Interface Improvements
  5. Part 5: Rendering a Buddy List
  6. Part 6: ListView Interaction
  7. Part 7: Receiving messages and interface fixes
  8. Part 8: Width based layout
  9. Part 9: Deploying your Kivy application

Interface Design

In general, before developing a user interface, it is a good idea to know what you want it to look like. I see this project having three main views. When the user first opens the application, they’ll see an Account Details screen to provide their jabber server and login credentials. We won’t bother with saving these details since this tutorial series is focused on Kivy interface development, not persistence. Once they have logged in, the other two views are a Buddy List and the individual Chat Window.

I would like to develop the app to show the buddy list and chat windows side by side if the screen is large enough (eg: a laptop screen or large tablet in horizontal orientation), but only one window at a time on small screens. It is very important to evaluate screen size when developing cross platform applications; it is generally not desirable or feasible to render the same view on large monitors and small phones. We’ll look at this feature in later tutorials, but knowing that we want to plan for it now will affect how we implement our design.

All of these windows are pretty simple. In this second part, we will focus on the account details screen. It will be a simple form with labels on the left and fields for entering the various details on the right. The fields covered will include server, username, and password. Below these fields will be a Login button. Normally I’d sketch the interface on a piece of paper, but since this looks like every other Jabber client on the market, I don’t think it’s necessary.

The Account Details Form Widget

In Kivy, virtually every object that gets displayed on the screen is a widget. Just a few examples include:

  • The label we rendered in the first tutorial
  • The text input fields and buttons we’ll render in this tutorial
  • Layout classes that contain other widgets and decide where they should be displayed
  • Complicated tree views such as file pickers
  • Movie and photo renderers
  • Tabbed boxes that display different widgets depending on the selected tab

It is easy to make custom widgets, and to access all widgets, whether custom or otherwise, from KV language files. We’ll be creating a new widget to contain our entire Account Details form. Start by adding a new import and class to


Running the code with this addition won’t change anything in the output, since the newly created widget hasn’t been added to the root window. However, there are a few things we need to discuss before we change the KV language file to use this widget. You might be asking yourself why we created a new widget instead of adding a BoxLayout widget (whatever that is!) directly to the root of the KV language file orkiv.kv. While it would have been trivial to do this, it would have made putting a new widget (such as the Buddy List) on the root screen more difficult. Further, when it comes time to attach events to the Login button, we can make it a method of this new class, where it makes the most sense.

The BoxLayout is a very simple widget that simply takes the available space and places all the child widgets in it from left to right or top to bottom. By default, each widget gets an equal amount of space, but it’s also possible to make certain widgets have specific sizes or percentages of space or to expand to fill available area.

BoxLayout is one of several kinds of layouts available in Kivy. A layout is simply a container widget that holds other widgets and knows how to position those child widgets in a specific pattern. We’ll be seeing a GridLayout shortly. You can read about other Kivy layouts in the Kivy API Reference.

Let’s edit orkiv.kv to render this new widget as the child form instead of the label we used before. We’ll also add a couple labels to the AccountDetailsForm class so you can see the relationship between root widgets and classes in the KV Language:


There’s a couple things going on here. The root widget of the Orkiv app is defined as a AccountDetailsForm. This is followed by a colon in case we wanted to add other child widgets to the object, but in this case, it’s just followed by a blank line. Then we define the structure of the child widgets of the AccountDetailsForm class itself. We know it’s a class and not a root widget because the class name is surrounded in angle brackets (< and >). Further, one app can only have one root widget. We just defined that root to be pointing at a single AccountDetailsForm. However, note that a class can be styled once and added in more than one place. Just as our AccountDetailsForm has two labels, it would be possible (though silly, from an interface perspective) to create a container widget that contains two AccountDetailsForms. The point is, an AccountDetailsForm, once its layout has been defined, can be used just like any of the built-in widgets supplied with Kivy.

If you run python orkiv now, it will render the two labels side by side, each taking a full half the window. Note that there are actually three widgets being rendered; first, the AccountDetailsForm (which is a BoxLayout by inheritance) is rendered to fill the whole screen, and then it lays out the two labels as child widgets.

However, that’s not the AccountDetailsForm we were looking for! Let’s create our first nontrivial Kivy Language class. Replace the class in your orkiv.kv with the following:


It’s time to discuss just how the Kivy language lays things out. In my mind, it uses a box model similar to HTML, except instead of ugly HTML tags, indentation is used to specify what widgets go inside other widgets. Also, unlike HTML, style information is included in the .kv file instead of an external .css file. Though it’s not a hard and fast rule, style information (called properties in Kivy) typically begins with a lowercase letter, while child widgets start with a capital.

Look at the first level of indentation under the <AccountDetailsForm> declaration. There are three items; orientation, GridLayout, and Button. The former counts as “style information”. Remember that the AccountDetailsForm class extends BoxLayout. One of the attributes on BoxLayout is “orientation”; we are telling BoxLayout here that we want a vertical layout.

This vertical box layout then contains two widgets, a GridLayout and a Button. The GridLayout spaces all it’s children equally. We just have to tell it that there are 2 columns (the cols property) and then start adding our objects, which are displayed from left to right and wrap to the next row in the grid after every two widgets. We add Labels and TextInputs. Each label has a text property that we set using a further level of indent. The TextInput objects don’t require any extra properties except the password.

Later, we’ll have to give these objects some identifiers so we can refer to them in code. For this initial prototyping stage, we can start with the bare minimum. If we render the above example, we end up with a recognizable, but rather ugly form:


Restricting sizes

Let’s try to make the form a little less ugly:


All we’ve done here is add some styling information to make the layout a little more friendly. This can be complicated as we want the app to look good on a variety of devices at a variety of resolutions and screen sizes. The main thing is to ensure all the widgets have a known height. As you might guess, this can be accomplished by adding a height property to each of the widgets. However, doing this alone will not work because BoxLayout likes to think of itself as in charge of deciding what size a widget should be. Without any styling, heights in a vertical BoxLayout are calculated as the number of widgets divided by the available screen space. However, it’s possible to tell BoxLayout to make certain widgets take a higher percentage of available space by giving it a size_hint_y attribute, which should be a float and defaults to 1.0. Unfortunately, for textboxes and buttons, percentages don’t really make a lot of sense, since we have no idea what size the window or screen of a particular advice is going to be, but we do know we want them to be about the same height on each screen.

So in addition to setting the height attribute, we also have to set size_hint_y to None for those widgets to prevent BoxLayout from ignoring the height property and laying things out by percentages instead.

You’ll also note that we are specifying the heights using strings that end in the suffix “dp”. It’s possible to provide integer values here, which would be interpreted as the number of pixels high the button is. However, due to the massive variance in screen resolutions on modern devices, it’s not really feasible to use pixels as a measurement. A login button that is 40 pixels high and looks good on a desktop monitor would look very small, indeed, on a “retina” display tablet.

Therefore, Kivy provides us with the concept of “display pixels”; hence the “dp” in the strings. Display pixels should be about the same size on every device; on a standard desktop monitor they generally map to a single pixel, but on higher density displays, they will be multiplied by a scaling factor. There are other metric properties such as cm or in that you can use, but I generally find it most convenient to think in display pixels.

Note also that instead of supplying heights for each of the Label and TextInput widgets inside the grid layout, we cheated and used the row_default_height attribute so all rows have the same height. For this to work, you also have to set row_force_default to True.

Finally we added spacing and padding properties to the GridLayout to add a 10dp space between child widgets and a “frame” around the whole GridLayout as well. If we run this example, it looks like this:


There’s one more thing I’d like to do before ending this part of the tutorial. As you can see above, the form is showing up at the bottom of the window, no matter what size the window is. That might look a bit bizarre on a tablet or even phone screen. It would be better if the entire form was anchored to the top of the window.

As an exercise, take a few moments to experiment (remember to use a different git branch!) and see if you can figure out how to move the form to the top by yourself. The next paragraph contains some hints if you get stuck, and the working code is linked after that. (I’m not about to tell you not to cheat, since it really depends what your personal goals are in reading this tutorial.)

There are probably multiple ways to do this, and I’m not even certain my solution is the best one. But I suggest making the AccountDetailsForm into an AnchorLayout and anchor a child BoxLayout to the top of the form. Note that you’ll have to change both files to make this happen.

If you’re still confused, have a look at the full changeset at the changeset on github.

That’s it for part 2 of this tutorial, which focused on laying out widgets in the KV Language. In part 3, we’ll figure out how to log into an XMPP library and render a buddy list. Note that I don’t actually know how to do this, so we’ll have to figure it out together!

Monetary feedback

When I wrote this tutorial, I didn’t expect it to be big or popular enough to publish as a book. However, the series caught O’Reilly’s eye, and I have since written an entire book on Kivy. If you want to support me and learn more about Kivy, you and I both will be delighted if you buy it.

If you like the tutorial and would like to see similar work published in the future, this isn’t the only way to support me. I hope to one day reduce my working hours at my day job to have more time to devote to open source development and technical writing. If you think this article was valuable enough that you would have paid for it, please consider thanking me in one or more of the following ways:

If you aren’t in the mood or financial position to help fund this work, at least share it on your favorite social platforms!

13 thoughts on “Creating an Application in Kivy: Part 2

  1. Pingback: Dusty's Diverse Domain » Blog Archive » Creating an Application In Kivy: Part 1

  2. Owais

    Kivy looks awesome. Only thing it is missing is native themes. I think that is a blocker for people trying to write apps for any platform. QT really shines there, QT apps look like Mac apps on a Mac and KDE apps on KDE and Gtk apps on Gnome. Yes, QT is not perfect when it comes to native styling but it’s close. I think Kivy could really become a great challenger to traditional (Gtk/QT) toolkits if it supported native styling in some way.

    1. Dusty Phillips Post author

      I’m not overly familiar with QT, but I did find PyQT to be “less pythonic” than I would like. I’ve always considered GUI toolkits to be a necessary evil, and none of them were ideal. However, Kivy is truly a joy to work with from a developer perspective. I’m amazed how often I write code and run it to find that it “just works” without having to reference the documentation.

      The default Kivy theme fits in with the android platform, though it isn’t a pixel for pixel native representation. On other devices it doesn’t fit in at all! However, Kivy does support advanced low-level theming (see, and I think this mechanism is still being improved. I would not be surprised to see native themes in Kivy’s future.

  3. Bryan Lott

    Just wanted to say that I’m still loving this tutorial and *really* appreciate that you’re building a non-trivial app w/ a .kv file, can’t wait for the next part!

    1. Dusty Phillips Post author

      I’m glad you’re enjoying it! I’m also enjoying writing it.

      I’m planning to release the parts on a one per week(ish) schedule.

  4. Adrian Klaver

    Took up your call to experiment.

    A StackLayout also works to move the widgets up:

    from kivy.uix.stacklayout import StackLayout

    class MainForm(StackLayout):

    class AccountDetailsForm(BoxLayout):


    orientation: “lr-tb”

    orientation: “vertical”

  5. Pingback: Dusty's Diverse Domain » Blog Archive » Creating an Application in Kivy: Part 3

  6. Pingback: Dusty Phillips: Creating an Application in Kivy: Part 3 | The Black Velvet Room

  7. Pingback: Dusty's Diverse Domain » Blog Archive » Creating an Application in Kivy: Part 4

  8. Pingback: Dusty's Diverse Domain » Blog Archive » Creating an Application in Kivy: Part 6

  9. Pingback: Dusty's Diverse Domain » Blog Archive » Creating an Application in Kivy: Part 8

  10. Pingback: Dusty's Diverse Domain » Blog Archive » Creating an Application in Kivy: Part 7

  11. Pingback: Dusty Phillips: Creating an Application in Kivy: Part 8 | The Black Velvet Room

Leave a Reply

Your email address will not be published. Required fields are marked *