This is the first in what I expect to be a series of tutorials on creating user interfaces in Kivy. Kivy is a cross platform user interface framework that allows us to write applications in Python that run on various desktop operating systems, Android, and IOS.
I’ve wanted to write a tutorial on Kivy since hacking on Python 3 support during the dev sprints at Pycon 2013. My goal is to create a useful application that runs on multiple devices and highlights use of the KV Language to design user interfaces. I also want this multi-part series to describe end-to-end how to develop, maintain, and deploy a Kivy application. I intend it to be a model for newcomers to Kivy and even Python to develop their own cross platform or mobile applications in Python. Thus, it doesn’t just include code, but also deployment instructions and information on how to use the git version control system for basic history management.
Therefore, this tutorial series is written at a more basic level than a lot of my technical articles. My intended audience is new programmers who have some basic Python experience; perhaps having read The Python Tutorial and Learn Python The Hard Way, but possibly not the beginner-intermediate topics covered in my book, Python 3 Object Oriented Programming.
Having decided to write a tutorial, I needed to decide what kind of application to develop. This actually took quite a bit of thought. I decided on a Jabber client, as it has a user interface with reasonable complexity, and I am hoping that most of the difficult bits can be abstracted away into the SleekXMPP library. Finally, I had to settle on a name for the app; I chose Orkiv. I do not know why.
Table Of Contents
A blog isn’t the best platform for publishing a multi-part tutorial. I’ll include a Table Of Contents section in each part with references to all the other parts. Hopefully I’ll even keep it up to date!
- Part 1: Introduction to Kivy
- Part 2: Creating a Form
- Part 3: Handling Events
- Part 4: Code and Interface Improvements
- Part 5: Rendering a Buddy List
- Part 6: ListView Interaction
- Part 7: Receiving messages and interface fixes
- Part 8: Width based layout
- Part 9: Deploying your Kivy application
Start by installing the following pre-requisites using standard operating system tools.
Python is the programming language and interpreter that Kivy programs are written in. Git is a version control system that we will use to track changes to our code. Virtualenv is a tool for creating isolated Python environments. Pip is an installer for installing python packages, in this case into the isolated virtualenv.
Note: Use of git is optional if you are more interested in learning to code than learning to manage a project. You are also welcome to use another version control system of your choice. At the level we will be working, the commands are virtually interchangeable.
Setting up the environment
Run the following commands in a terminal. (Note this tutorial was written using Arch Linux, and will probably work flawlessly on MacOS and other Linux distributions. However, you may need to do some experimenting to make Windows cooperate).
mkdir orkiv cd orkiv git init virtualenv -p python2.7 venv echo venv >> .gitignore echo "*.pyc" >> .gitignore git add .gitignore git commit -m "Create .gitignore file. Ignores compiled python files and venv." source venv/bin/activate
We’re creating a directory to hold our project and then initialize a git repository in there. We next create a virtualenv in a folder named
venv. This folder will hold the isolated python files so that you can interact with Kivy without adding cruft to your system Python. I highly recommend creating a separate virtualenv for every project you work on.
Next, we set up a
.gitignore file that tells git not to track certain files in our repository; in this instance all compiled python files, which end in
.pyc, and the virtualenv directory we just created. We commit the changes to this file as our first commit in the git repository.
Finally, we “turn on” the virtualenv by sourcing its activate script. This essentially tells our shell to “use the isolated python for this project instead of system python”. When you are done working on this project, you should enter the command
deactivate. When you come back to the project in the future, reenter the
source venv/bin/activate command to turn on the isolated environment.
Note: If you maintain a lot of virtualenvs in a lot of different projects, as I do, you may be interested in a small script I wrote to facilitate switching between them.
Kivy depends on several Python libraries. Unfortunately, it does not have a setuptools-enabled setup.py to automatically install these dependencies into our virtualenv, so we have to do a little work ourselves. This takes a while, but if you copy paste these commands into your terminal, you should get lucky.
pip install cython pip install pygame
Sadly, on Arch Linux, the last command, for pygame fails. I suspect it works fine on less bleeding edge operating systems, however, if you encounter an error about
linux/videodev.h not existing, applying the Arch Linux patch to pygame may get you to the next step.
wget http://www.pygame.org/ftp/pygame-1.9.1release.tar.gz wget https://projects.archlinux.org/svntogit/packages.git/plain/trunk/pygame-v4l.patch?h=packages/python-pygame -O pygame-v4l.patch tar xf pygame-1.9.1release.tar.gz cd pygame-1.9.1release/ patch -Np1 -i ../pygame-v4l.patch python setup.py install cd .. rm pygame* -r
And now, you should finally be ready to install Kivy itself: This will take a while, so grab a smoothie while it runs:
pip install kivy python -c 'import kivy'
The latter command should output the kivy version (I’m working with 1.7.1). If it exits without failure, then you have successfully installed Kivy!
Now let’s create a basic Kivy app
Create a directory to hold the application code:
This directory will contain your Python and Kivy source files. Our goal is to be able to always create a zipfile from this directory and be able to run it using python
orkiv.zip. As long as the required dependencies are installed on the target system (as described above), the program should run. It will therefore be nice and self-contained.
There is a relatively unknown feature of recent versions of Python to support this. If a directory or zipfile contains a
__main__.py, that module will be executed if python is called with that directory or zipfile as an argument. First, create a file inside the new orkiv directory named
__main__.py. Create a simple “hello world” in this file to test that
Now from the parent directory, run the command
python orkiv. If you want to test it with a zipfile, try this:
cd orkiv zip ../orkiv.zip * cd .. python orkiv.zip
It is possible to code Kivy applications in pure Python, but in my opinion, it is much better to use the amazing KV Language to do layouts. The basic approach is to have a Python file (in our case
__main__.py above) that contains the logic for the application, and a KV Language file that contains the layout information. The KV Language is very similar to Python and you can learn it as you go.
Lets start by removing the
__main__.py and replacing it with the most basic possible Kivy application:
from kivy.app import App class Orkiv(App): pass Orkiv().run()
This simply imports a Kivy
App class and creates a subclass of it using Python’s notoriously simple inheritance syntax. Inheritance is a useful feature of Object Oriented Programming that basically means that a class can be defined that has all the functionality of the parent class. In this case, since we didn’t add anything to the subclass, that’s ALL it has. However, the true beauty of inheritance is that we can add new properties and methods (functions attached to objects) to the subclass or even change the functionality that comes with the parent class (
App). The best part is, we don’t really have to know what is going on inside the
App, and can assume the Kivy devs know what they are doing.
It doesn’t even add anything to the subclass! Then it instantiates an instance of that subclass and calls the
run() method on the newly created object.
If you run
python orkiv with the new code saved, you’ll see an empty window pop up.
As far as boilerplate goes, that’s pretty damn concise, don’t you think? The amazing thing is that we can start laying out KV Language widgets in a separate file without touching this boilerplate at all! Don’t believe me? Try saving the following as
Label: text: "hello world"
Now if you run
python orkiv, you should see the “hello world” label centered in the window that pops up. It’s almost like magic, and if you’re like me, you’re probably wondering how that’s even possible.
When you create a subclass of a
kivy.app.App, it introspects the name of the new class (we named it
Orkiv). Then it looks for a file in the same directory that follows these rules:
- Ends with the
- Starts with the name of the class converted to lowercase and with any
trailing App stripped.
The Kivy documentation would have named the class
OrkivApp and still used the
orkiv.kv filename. Personally, I don’t see the redundant need to add
App to the class name, since the inheritance structure clearly indicates that
Orkiv is a
We’ll be working with the Kivy Language a lot as we proceed through each part of this tutorial. You’ll soon see that it’s possible to do more, a lot more, than add a label to a window!
A note on version control
At this point, you’ve created a logical related set of changes that are in a working state. I want to encourage you to experiment with these files, maybe change the contents of the label, try a different application and KV Language filename, or see if you can figure out how to group two labels into a single layout. But before doing that, you should record this known state that your repository is currently in so it’s easy to get back to. That way, you can be free to explore without fear of getting completely lost; you’ll always have a path straight back to your current state. You can do that from the command line using git:
git add orkiv/ git commit -m "A basic Kivy boiler plate"
You just made a commit on the
master branch in git. First you listed the changes you wanted to include in the commit (the entirety of every file in the new orkiv directory), then you told git to record the current state of those files forever. It is generally recommended that you only save consistent, known-to-be-working state on the
master branch. For the purposes of this tutorial, I suggest that you only save the code you copied from the tutorial to the
master branch, and do your other development on other branches.
Are you confused by what a branch is, exactly? Think of it like walking down a forest path in a national park. You are following signs for a marked trail; that’s this tutorial. As you walk, you see things that you want to remember, so you take a photo. That’s like making a commit on the master branch. However, you also see side paths that you would like to explore on your own. You can go down that path as far as you want, or even take other random paths without fear of getting lost. You can even take photos on those paths, knowing they won’t get mixed in with the photos from the main trail. Then when you want to return to the point where you left the main trail, you can magically teleport back to it (or indeed, to any of the other branches you walked down in your exploration).
You probably won’t be doing it for this tutorial, but the most import aspect of version control is that if you are in unmarked forest rather than a national park, you can walk down all the paths and decide which one you’re going to choose as the main path. You can even merge paths back into each other so that the photos (code commits) taken on each of them end up in the same final presentation.
Enough digressing! For your purposes, the first thing you should do is create a new branch in git:
git checkout -b my_exploration
You are now on a new branch named
my_exploration (you can call each branch whatever you want, of course) that is exactly the same as the master branch as you last saw it. But you can make changes on that branch to your heart’s content; you can add and commit them as above if you want to remember them for later. When you’re ready to come back to the tutorial, you can use this command to return to the current state of the master branch:
git checkout master
From there, you could continue with the next part of the tutorial, or you could create a new branch and explore in a different direction.
Browsing the examples
I am maintaining my own version of the code developed in this tutorial at https://github.com/buchuki/orkiv/. However, it’s not likely to be the same as your repository, since I’m not making commits at the same time that I’m suggesting you make commits. Instead, my master branch contains a separate commit for each example in the tutorial. I also create git tags for each part of the tutorial so it’s fairly easy to see from commit history what was covered in each part. If you browse the Commit History you can see each example and how it evolved from top to bottom. You can view the list of tags here.
I don’t expect the collected parts of this tutorial to be big enough to publish as a book, so I’m hosting them for free here on my blog. If you like the tutorial and would like to see similar work published in the future, please 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:
- Purchase my books: Python 3 Object Oriented Programming and Hacking Happy
- Tip me on Gittip
- E-mail dusty at archlinux dot ca to let me know you would fund a book about Kivy via crowd funding
If you aren’t in the mood or financial position to help fund this work, at least share it on your favorite social platforms!