Python on Android? First impressions of Kivy

Kivy is a modern cross-platform Python GUI toolkit that runs on mobile devices (Android and IPhone) and supports modern input events (multitouch, accelerometor). I was really skeptical at first, but I spent the weekend developing an app in Kivy, and now I’m hooked.

In the past, I have tried most of the available Python GUI toolkits (even Swing, through jython). In recent history, I’ve mostly done HTML based interfaces, partially because that’s where the money has been, but mostly because pyQT, pyGTK,wxpython, and tk are all painful to work with.

In Kivy, interfaces are defined in a language called (aptly) the Kivy Language. The best way to describe the Kivy Language is “what HTML5 wishes it was.” It is mostly just a layout language, but it also supports binding properties and events using inline Python snippets. It is indentation defined, like Python, and utilizes a minimal amount of syntax with a maximal amount of readability. It is vaguely reminiscent of CoffeeKup but cleaner, and doesn’t suffer from having to be compiled to HTML. I love how it mimics Python syntax, but also clearly separates presentation from control code.

My favourite feature of Kivy is that properties are events. You can easily hook a property on one widget to the property on another. For example, I wrote a simple demo that connects the value of a slider to the value of a progressbar:

BoxLayout:
    orientation: 'vertical'
    ProgressBar:
        id: bar
        value: 14
        max: 20
    Slider:
        id: slider
        max: 200
        value: 140
        on_value: bar.value = self.value / 10

When the value property on the slider changes (whether because the user moved the slider, or because it was adjusted programmatically in response to some other event), the on_value event is fired. This is connected to the value of the progress bar using a Python snippet.

Only a few lines of Python code are required to to get a Kivy application running once its interface has been defined in Kivy language. The Kivy Hello World example is actually overly complicated because it doesn’t actually use the Kivy language. The bare essentials, if the above file is named sample.kv is:

from kivy.app import App
class SampleApp(App): pass
SampleApp().run()

Just three lines of code. Kivy introspects the class name (convention over configuration) and automatically loads sample.kv as the interface for a class named SampleApp.

The Kivy API is very simple. In fact, my earliest impression was that it was almost amateurish. It felt like if I wanted to do anything serious with it, I’d be disappointed. It’s the kind of API I would teach a child. However, the few features of the API (basically properties, events, and graphics instructions) are extremely well thought out and well-defined. They can be combined like Lego bricks to create widgets as complicated as one could possibly wish. The fact that the library includes a ReStructured Text rendering widget is testament to that fact!

Kivy is extremely well documented. I actually found their pong tutorial exciting. Seeing how simple it was to do each step actually made me giggle out loud. The programmer’s guide and API are well presented as well. Further, if you get stuck, the developers on IRC are terrific. I felt like I was an accepted member of the team after asking only one question.

Drawbacks

It took a bit of fiddling to get Kivy to install correctly under Arch Linux. I suppose if I’d followed the instructions, all would have been well. However, I like to do all my development in a virtualenv, and there is no trivial way to track down and install all Kivy’s dependencies. This is especially compounded by the fact that pygame currently needs to be patched under Arch in order to compile.

There are instructions for packaging your Kivy app onto Android, but I wasn’t able to pull it off, yet. I’ll have to revisit it when I have more time.

I tried some sample Kivy apps in the Android market. They work just fine once they are loaded, but it takes each app several seconds to initialize on my Galaxy Nexus. Hopefully the Kivy team can reduce this load time. I don’t know if Kivy supports displaying a splash screen while stuff is loading; that would certainly enhance the usability.

Most of these issues are solvable. I’m sure the team is actively working on some of them. Kivy is a quite young project, but it is remarkably mature.

Kivy Catalog

My weekend project was the Kivy Catalog, an interactive showcase of Kivy widgets. It allows you to view the Kivy language code used to define the widgets and to edit it and see what effects your changes have. I think it will be a tremendous aid to users looking to get started with the Kivy language. Developing it certainly was for me!

I am expecting to have this code included with the Kivy distribution in the examples directory in a future release.

19 Comments

  1. anonymity is great says:

    This sounds pretty much similar to QML which is a declarative language for Qt. In QML you can add javascript code, but it is also possible to interface with a C++ backend. Nice to see that a declarative language also exists for Python. What I like very much about QML is the bindings: your on_value event would be replaced by a binding “value: slider.value / 10″ instead of “value: 14″ in the definition of bar. Then bar.value adapts automatically each time slider.value changes, which is great. The slowness at startup is likely to be caused by the fact that the declarative language must be compiled to real Python code first. Because of the bindings the declarative files must *all* be parsed before anything can be shown.

  2. tshirtman says:

    @anonymity is great: actually you can do “value: slider.value / 10″ in kv, the example would work with that change, i guess OP wanted to show that you can trigger arbitrary python expression on change, but you can totally do it the way you suggest :).

    For the slowness at start on android, it’s mostly for the first start, and it’s because it comes with everything in a zip (python compiled for arm, all the required libs, and all of your assets) and it needs to unarchive it on first launch, kv code is not compiled to python code, it’s interpreted directly by a parser written in python (lang.py in kivy) and it’s really fast.

  3. Kivy user says:

    “What I like very much about QML is the bindings: your on_value event would be replaced by a binding “value: slider.value / 10″ instead of “value: 14″ in the definition of bar.”

    The same thing can be done with the Kivy Language, one can simply do “value: slider.value / 10″ for binding it to the slider value.

    They also provide a VirtualBox[http://python-for-android.readthedocs.org/en/latest/prerequisites/] image that has everything pre-installed for creating a apk.

    About the load time. For the first load the kivy apps basically extract’s itself, and it’s dependencies therefore takes longer to load the first time. Loading the same app second time onwards should be a lot faster, at-least it was for me.

    Good to see people other than me having fun with kivy.

  4. Ewald says:

    I’m using Kivy on Kubuntu and I had absolutely no problems installing or running it. The start-up time on my tablet is comparable to other applications (After the initial start) and I’m very happily learning more about Android development while using the lovely Python language.

    Kivy is a great product and I think it has a bright future.

  5. Mylash says:

    I think it is very interesting. I have played around with the basics too and find it powerful, but I do not have any experience with mobile app development so cannot make direct comparisons.

    It definitely lowers the boundaries for mobile app development.

  6. [...] across this article on Kivy for Android on Hacker News. According to kivy.org, Kivy is an open source Python library [...]

  7. [...] Python on Android? First impressions of Kivy [...]

  8. aspidites says:

    Nice to see another Archer using Kivy. As I just got a GN, it’s even nicer to see that it plays nicely with that phone.

    I must say I didn’t have the same issues when installing Kivy, but this might simply be because I wasn’t using virtenv. I wonder if in the port to 3.3 will assist in that regard.

    It may be worth while opening an issue about the splash screen, too.

  9. [...] Kivy is a modern cross-platform Python GUI toolkit that runs on mobile devices (Android and iPhone) and supports modern input events (multitouch, accelerometor). The best way to describe the Kivy Language is “what HTML5 wishes it was.” It is mostly just a layout language, but it also supports binding properties and events using inline Python snippets. It is indentation defined, like Python, and utilizes a minimal amount of syntax with a maximal amount of readability. You can checkout sample here. [...]

  10. [...] Dusty’s Diverse Domain » Blog Archive » Python on Android? First impressions of Kivy [...]

  11. xyproto says:

    To make kivy-for-android work on Arch Linux, replace /usr/bin/env python with /usr/bin/env python2 (or just /usr/bin/python2) everywhere. Then replace cython with cython2 (and make sure cython2 is installed). This made ./distribute.sh -m ‘kivy’ work here. gl.

  12. xyproto says:

    Remember to export ANDROIDAPI as well.