Creating an Application in Kivy: Part 5

In Part 4, we took a break from developing Kivy interfaces and focused on improving the interface we already had. In this part, we’ll get back to interface development by creating a widget to display the buddy list. Here’s the plan: we’ll start with a new widget to render the information we’re getting from the roster. Then we’ll figure out how to query sleekxmpp to get additional information about the user, such as their online status and status message.

If you haven’t been following along or want to start with a clean slate, you can clone the state of the example repository as of the end of part 4:

git clone https://github.com/buchuki/orkiv.git
git checkout end_part_four

Remember to create and activate a virtualenv populated with the appropriate dependencies, as discussed in part 1.

Table Of Contents

If you’re just joining us, you might want to jump to earlier steps in this tutorial:

  1. Part 1: Introduction to Kivy
  2. Part 2: A basic KV Language interface
  3. Part 3: Handling events
  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

Rendering A Basic ListView

So far, after successful login, a list of usernames is printed on the ConnectionModal popup. That’s not quite what we want to do. Rather, we want to dismiss the popup and render the buddy list in the root window instead of the login form.

The first thing we’ll have to do here is wrap the login form in a new root widget. We should have done this from the start, but to be honest, I didn’t think of it. This widget will be a sort of manager for the AccountDetailsForm, BuddyList, and ChatWindow. If we only ever wanted to show one window at a time, we could use Kivy’s ScreenManager class to great effect. However, I hope to display widgets side by side if the window is wide enough, so let’s try coding it up manually.

First we can add an OrkivRoot (leaving it empty for now) class to __main__.py. Let’s add a BuddyList class while we’re at it, since we’ll need that shortly.

(commit)

from kivy.uix.boxlayout import BoxLayout  # at top of file

class BuddyList(BoxLayout):
    pass


class OrkivRoot(BoxLayout):
    pass

Next, we update the orkiv.kv to make OrkivRoot the new root object (replacing the current AccountDetailsForm: opening line) and make any instances of OrkivRoot contain an AccountDetailsForm:

(commit)

OrkivRoot:

<OrkivRoot>:
    AccountDetailsForm:

Now let’s add a show_buddy_list method to the OrkivRoot class. This method will simply clear the contents of the widget and construct a new BuddyList object for now:

(commit)

class OrkivRoot(BoxLayout):
    def show_buddy_list(self):
        self.clear_widgets()
        self.buddy_list = BuddyList()
        self.add_widget(self.buddy_list)

And finally, we can remove the temporary code that renders buddy list jabberids on the ConnectionModal label and replace it with a call to show_buddy_list:

(commit)

def connect_to_jabber(self):
    app = Orkiv.get_running_app()
    try:
        app.connect_to_jabber(self.jabber_id, self.password)
        app.root.show_buddy_list()
        self.dismiss()

Note that we also explicitly dismiss the ConnectionModal. The new BuddyList widget, which is currently blank, will be displayed as soon as we have a valid connection.

Let’s add some styling to that BuddyList class in our orkiv.kv file. We’ll add a ListView which provides a scrollable list of widgets. Of course, we’re not actually putting anything into the ListView, so if we run it now, it won’t show anything… but it’s there!

(commit)

<BuddyList>:
    list_view: list_view
    ListView:
        id: list_view

Notice that I gave the ListView an id property and connected it to a list_view property on the root widget. If you remember part 3 at all, you’re probably expecting to add an ObjectProperty to the BuddyList class next. You’re right!

(commit)

class BuddyList(BoxLayout):
    list_view = ObjectProperty()

    def __init__(self):
        super(BuddyList, self).__init__()
        self.app = Orkiv.get_running_app()
        self.list_view.adapter.data = sorted(self.app.xmpp.client_roster.keys())

Since you guessed that ObjectProperty was coming, I added an initializer as well. I have to keep you interested, after all! The initializer first sets up the superclass, then sets the list_view‘s data to the buddy list keys we’ve been using all along. There’s a couple complexities in this line of code, though. First note the call to sorted, which accepts a python list (in this case containing the ids in the buddy list) and returns a copy of the list in alphabetical order. Second, we are setting the list_view.adapter.data property. Underneath the hood, ListView has constructed a SimpleListAdapter for us. This object has a data property that contains a list of strings. As soon as that list is updated, the adapter and ListView work together to update the display.

The reason that the data is stored in an adapter is to separate the data representation from the controller that renders that data. Thus, different types of adapters can be used to represent different types of data. It’s possible to construct your own adapter as long as you implement the relevant methods, but this is typically unnecessary because the adapters that come with Kivy are quite versatile.

Try running this code. Upon successful login, the modal dialog disappears and the buddy list pops up in sorted order. Resize the window to be smaller than the list and you can even see that the ListView takes care of scrolling.

The SimpleListAdapter is not sufficient for our needs. We need to be able to display additional information such as the user’s status and availability, and we want to lay it out in a pretty way. We’ll also eventually want to allow selecting of a Buddy in the list so we can chat with them. SimpleListAdapter supports none of this. However, Kivy’s ListAdapter does. So let’s edit the orkiv.kv to use a ListAdapter for the BuddyList class:

(commit)

# at top of file:
#:import la kivy.adapters.listadapter  # at top of file
#:import lbl kivy.uix.label

<BuddyList>:
    list_view: list_view
    ListView:
        id: list_view
        adapter: la.ListAdapter(data=[], cls=lbl.Label)

First, we import the listadapter module using the name la. This has a similar effect to a from kivy.adapters import listadapter as la line in a standard Python file. This #:import syntax can be used to import any python module that you might need inside the kv language file. The syntax is always #:import <alias> <module_path>. However, you can only import modules, you can’t import specific classes inside modules. This is why I used a rather uninformative variable name (la). When we construct the ListAdapter at the end of the snippet, the shortened form happens to be more readable, since we are immediately following it by a class name.

We also import the label class as lbl. While it seems odd to have to import Label when we have seen Label used in other parts of the KVLanguage file, we have to remember that sometimes KV Language allows us to switch to normal Python. That’s what’s happening here; the code after adapter: is normal python code that doesn’t know about the magic stuff Kivy has imported. So we have to import it explicitly.

This is probably not the best way to do this; we’re probably going to have to replace this view with a custom ListView subclass later, but it suits our needs for the time being.

That code is simply constructing a new ListAdapter object. It assigns empty data (that will be replaced in BuddyList.__init__) and tells the ListAdapter that the cls to render the data should be a Label. So when we run this code, we see a scrollable list of Labelcode> objects each with their text attribute automatically set to one of the jabber ids we set up in the BuddyList initializer.

However, a Label still isn’t the right widget for rendering a buddy list item. We need to show more information in there, like whether they are available or away and what their status message is. A label won’t cover this, at least not cleanly, so let’s start writing a custom widget instead.

First, add a BuddyListItem class to the __main__.py:

(commit)

from kivy.properties import StringProperty  # At top of file

class BuddyListItem(BoxLayout):
    text = StringProperty()

By default, ListAdapter passes a text property into the widget that is used as its cls. So we hook up such a property which will be rendered by the label in the KV language file. This is a StringProperty, which behaves like any other property but is restricted to character content. Now we can use this class in the KV Language file:

(commit)

# at top of file:
#:import ok __main__

<BuddyListItem>:
    size_hint_y: None
    height: "100dp"
    Label:
        text: root.text

<BuddyList>:
    list_view: list_view
    ListView:
        id: list_view
        adapter: la.ListAdapter(data=[], cls=ok.BuddyListItem)

Don’t forget to make the adapter cls point at the new BuddyListItem class. You can also remove the Label import at the top.

We set a height property on the BuddyListItem mostly just to demonstrate that the custom class is being used when we run the app. Notice also how the label is referencing the root.text property we set up in the python file.

This property is being set, seemingly by magic, to the value from the data list we set on ListAdapter. In fact, it’s not magic; Kivy is just doing a lot of work on our behalf. For each string in that list, it’s constructing a new BuddyListItem object and adding it to that scrollable window. It then sets properties on that object using its default arg_converter. The arg_converter is responsible for taking an item from a data list and converting it to a dictionary of properties to be set on the cls object. The default is to simply take a string and set the text property to that string. Not so magic after all.

And now we’re going to make it less magic. Instead of a text property, let’s make a few properties that better reflect the kind of data we want to display:

(commit)

class BuddyListItem(BoxLayout):
    jabberid = StringProperty()
    full_name = StringProperty()
    status_message = StringProperty()
    online_status = StringProperty()

Don’t try running this without updating the KV file, since it’s trying to reference a text property that is no longer there:

(commit)

<BuddyListItem>:
    size_hint_y: None
    height: "40dp"
    Label:
        text: root.jabberid
    Label:
        text: root.full_name
    Label:
        text: root.status_message
    Label:
        text: root.online_status

Of course, running it in this state will bring us an empty window, since the ListAdapter is still using the default args_converter. Let’s add a new method to the BuddyList class. Make sure you’re sitting down for this one, it’s a bit complicated:

(commit)

def roster_converter(self, index, jabberid):
    result = {
        "jabberid": jabberid,
        "full_name": self.app.xmpp.client_roster[jabberid]['name']
    }

    presence = sorted(
        self.app.xmpp.client_roster.presence(jabberid).values(),
        key=lambda p: p.get("priority", 100), reverse=True)

    if presence:
        result['status_message'] = presence[0].get('status', '')
        show = presence[0].get('show')
        result['online_status'] = show if show else "available"
    else:
        result['status_message'] = ""
        result['online_status'] = "offline"

    return result

Deep breaths, we’ll explore this code one line at a time. First, the new method is named roster_converter and takes two arguments, the index of the item in the list (which we’ll ignore for now), and the jabberid coming in from the data list. These are the normal arguments for any ListAdapter args_converter in Kivy.

Next, we start constructing the result dictionary that we’ll be returning from this method. Its keys are the properties in the BuddyListItem class. It’s values, of course, will be displayed on the window.

Then we ask sleekxmpp to give us presence information about the user in question. This is not a trivial piece of code. I don’t want to spend a lot of time on it, since it involves ugly Jabber and sleekxmpp details, and our focus is on Kivy. In fact, you can skip the next paragraph if you’re not interested.

First, sleekxmpp’s client_roster.presence method returns a dictionary mapping connected resources to information about that resource. For simplicity, we’re ignoring resources here, but the basic idea is that you can be connected from two locations, say your cell phone and your laptop, and you’ll have two sets of presence information. Since we don’t care about resources, we ignore the keys in the dictionary and ask for just the values(). However, we still need to pick the “most important” resource as the one that we want to get presence information from. We do this by wrapping the list in the sorted function. Each resource has an integer priority, and the highest priority is the resource we want. So we tell the sorted function to sort by priority, passing it a key argument that gets the priority using a lambda function. The function defaults to 100 if the resource doesn’t specify a priority; thus we prefer an empty priority over any other value. The reversed keyword puts the highest priority at the front of the list.

Seriously, I hope you skipped that, because it’s a lot of information that is not too pertinent to this tutorial, even if the code it describes is. It took me a lot of trial and error to come up with this code, so just be glad you don’t have to!

So, assuming a list of resources is returned for the given jabber id, we pick the front one off the list, which is the one deemed to have highest priority. We then set the status_message directly from that item, defaulting to an empty string if they user hasn’t set one. The show key in this dict may return the empty string if the user is online (available) without an explicit status, so we check if the value is set and default to “available” if it is not.

However, there’s a chance that call returns a completely empty list which tells us what?: That the user is not online. So we have that else clause constructing a fake presence dict indicating that the user is offline.

Finally, things become simple again. We return the constructed dictionary that maps property names to values, and let Kivy populate the list for us. All we have to do for that to happen is tell Kivy to use our custom args_converter instead of the default one. Change the adapter property in the KV Language file to:

(commit)

adapter:
    la.ListAdapter(data=[], cls=ok.BuddyListItem,
    args_converter=root.roster_converter)

Notice that I split the command into two lines (indentation is important, if a bit bizarre.) in order to conform to pep 8‘s suggestion that line length always be less than 80 characters.

Now, finally, if you run this code and login, you should see all the information about your buddies pop up! However, it’s still a wee bit ugly. Let’s find some ways to spice it up.

One simple thing we can do is highlight different rows by giving each one a background color. We can start by adding a background attribute as an ObjectProperty to the BuddyListItem. Then we can set this value inside the roster_converter:

(commit)

if index % 2:
    result['background'] = (0, 0, 0, 1)
else:
    result['background'] = (0.05, 0.05, 0.07, 1)

Remember that index parameter that is passed into all args_converters and we were ignoring. Turns out it comes in handy. We can take the modulo (that’s the remainder after integer devision if you didn’t know) 2 of this value to determine if it’s an even or odd numbered row. If it’s odd (the remainder is not zero), then we set the background to black. Otherwise, we set it to almost black, a very deep navy. The background color is set as a tuple of 4 values, the RGBA value (Red, Green, Blue, Alpha). Each of those takes a float between 0 and 1 representing the percentage of each of those to add to the color.

Now, most Kivy widgets don’t have a background attribute, so we’re going to have to draw a full screen rectangle on the widget’s canvas. This is great news for you, because we get to cover the canvas or graphics instructions, something this tutorial has neglected so far. The canvas is a drawing surface that accepts arbitrary drawing commands. You can think of it as lower level than widget, although in reality, widgets are also drawn on the canvas, and every widget has a canvas. Here’s how we set up a rectangle on the BuddyListItem canvas:

(commit)

canvas.before:
    Color:
        rgba: self.background
    Rectangle:
        pos: self.pos
        size: self.size

I put this code above the labels in the BudyListItem. The canvas.before directive says “issue this group of commands before painting the rest of the widget”. We first issue a Color command, setting its rgba attribute to the 4-tuple we defined as the background. Then we issue a Rectangle instruction, using the currently set Color and setting the position and size to be dynamically bound to the size of the window. If you resize the window, the rectangle will be automatically redrawn at the correct size.

Another thing I want to do to improve the interface is render status messages underneath the username. They could go in a smaller font and maybe different color. This can be done entirely in KV Language:

(commit)

<BuddyListItem>:
    size_hint_y: None
    height: "75dp"
    canvas.before:
        Color:
            rgba: self.background
        Rectangle:
            pos: self.pos
            size: self.size
    
    BoxLayout:
        size_hint_x: 3
        orientation: 'vertical'
        Label:
            text: root.jabberid
            font_size: "25dp"
            size_hint_y: 0.7
        Label:
            text: root.status_message
            color: (0.5, 0.5, 0.5, 1.0)
            font_size: "15dp"
            size_hint_y: 0.3
    Label:
        text: root.full_name
    Label:
        text: root.online_status

I changed the height of the rows to be more friendly. The canvas I left alone, but I added a BoxLayout around two of the labels to stack one above the other in a vertical orientation. I made this BoxLayout 3 times as wide as the other boxes in the horizontal layout by giving it a size_hint_x. The two labels also get size hints, font size, and a color.

When we run this it looks… a little better. Actually, it still looks like ass, but this is because of my incompetence as a designer and has nothing to do with Kivy!

Now one more thing I’d like to do is render a status icon instead of the text “available”, “offline”, etc. Before we can do that, we need some icons. I wanted something in the public domain since licensing on this tutorial is a bit hazy. A web search found this library and I found some public domain icons named circle_<color> there. I grabbed four of them using wget:

(commit)

cd orkiv
mkdir icons
wget http://openiconlibrary.sourceforge.net/gallery2/open_icon_library-full/icons/png/48x48/others/circle_green.png -O icons/available.png
wget http://openiconlibrary.sourceforge.net/gallery2/open_icon_library-full/icons/png/48x48/others/circle_grey.png -O icons/offline.png
wget http://openiconlibrary.sourceforge.net/gallery2/open_icon_library-full/icons/png/48x48/others/circle_yellow.png -O icons/xa.png 
wget http://openiconlibrary.sourceforge.net/gallery2/open_icon_library-full/icons/png/48x48/others/circle_red.png -O icons/away.png

Once the files are saved, all we have to do to render them is replace the online_status label with an Image:

(commit)

    Image:
        source: "orkiv/icons/" + root.online_status + ".png"

And that’s it for part 5. I promised we would render a complete buddy list, and that’s what we’ve done! In part 6, we’ll make this list interactive. Until then, happy hacking!

Monetary feedback

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

Finally, if you aren’t in the mood or financial position to help fund this work, you can always share it on your favorite social platforms.

Creating an Application in Kivy: Part 4

You know, when I was doing my planning, I expected Part 3 of this tutorial to get us all the way to rendering a window containing the buddy list. So it’s somewhat amusing that this time, I don’t expect to be at that state at the end of this part. Instead, I want to focus on a few problems and annoyances with the existing code. Never fear, though, we’ll definitely be back to coding Kivy interfaces in Part 5!

In this part, we’ll focus on fixing a problem with the interface, handling errors on login, and taking care of that need to call “disconnect” on the xmpp object after displaying the buddy list. Be forewarned however! You may also encounter digressions on version control, debugging, and testing.

If you’ve gotten lost or want to jump in without doing the previous tutorials, you can start from the example repository as of the end of part 3:

git clone https://github.com/buchuki/orkiv.git
git checkout end_part_three

Table Of Contents

Here are links to other parts of this tutorial.

  1. Part 1: Introduction to Kivy
  2. Part 2: A basic KV Language interface
  3. Part 3: Handling Events
  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

Handling tab and enter events on text input

When I was testing the interface in part 2, I found that I naturally wanted to tab from one textfield to another, a common paradigm for desktop interfaces. Most desktop oriented toolkits have built-in support for what they call “tab order”; the order in which focus switches from one field to another when the tab key is pressed. Kivy doesn’t supply any tools for this. I think this highlights both Kivy’s emphasis on keeping a simple API and the fact that a lot of it was designed to work with mobile devices, which typically interact by touch and have neither physical keyboards nor a tab key. However, that doesn’t mean we can’t tab between our fields, it just means we have to do a bit more legwork.

Legwork generally starts with a web search. Lately, I wonder if I shouldn’t exercise my brain to come up with a solution on my own before turning to a search engine. However, deadlines are always tight, and Stack Overflow so often has an answer. Now, the code provided there doesn’t work quite the way I want it to, but it does tell us how to move forward in solving this task. Let’s get our hands dirty. We can start by adding a new class to our __main__.py:

(commit)

from kivy.uix.textinput import TextInput  # At the top

class AccountDetailsTextInput(TextInput):
    next = ObjectProperty()

    def _keyboard_on_key_down(self, window, keycode, text, modifiers):
        if keycode[0] == 9:  # 9 is the keycode for 
            self.next.focus = True
        elif keycode[0] == 13:  # 13 is the keycode for 
            self.parent.parent.parent.login()  # this is not future friendly
        else:
            super(AccountDetailsTextInput, self)._keyboard_on_key_down(
                    window, keycode, text, modifiers)

Yikes! That’s a little bit more complex piece of code than we’ve seen so far. It’s a good thing it’s so short! Let’s go through each staement. We start by creating a new widget called AccountDetailsTextInput that inherits from TextInput. This means that it looks and behaves exactly like a TextInput object… because it is one! However, we modify it a bit. First, we give it a next ObjectProperty just like we did to register TextInputs as properties on the AccountDetailsForm class in Part 3. We’ll be assigning a value to this next property inside the KV Language file later.

Then we override the _keyboard_on_key_down method on TextInput. You’re probably wondering how I knew that was the method I needed to override. Admittedly, the Stack Overflow answer provided a good hint, but I also read through the Kivy source code to make sure I knew what I was overriding and how it worked. Reading through other people’s source code can be intimidating, but is is the absolute best way to understand how something works. It’s also extremely educational, especially if you come across constructs that you don’t understand and have to look them up.

If you’re not familiar with Object Oriented Programming, you might want an explanation of what “overriding” is. Basically, whenever this method is called, we want it to do something different from what would happen if the same method were called on the parent class. Specifically, we want to handle the and keypresses in a different way.

So that’s what the conditional inside the method does. It checks the keycode value to see if it is 9 or 13. I didn’t know that the keycode was a tuple, but the source code and stack overflow question both indicated that the first value stores the keycode. I do happen to know that 9 and 13 are the keycodes for tab and enter because I’ve written similar handlers before. Can you think of a way (other than the aforementioned search engine) to determine what the keycode is for a given keypress?

Instead of the conditional in the code above, you could simply do a print(keycode[0]) inside this method and hook up the appropriate KV language syntax as we’ll discuss below. When you run the program, you’d be able to see the output on the console when the tab or enter key was pressed. There’s the information you need. Run with it!

The line where we focus the next object property is pretty straightforward; we just set a boolean value on it and let Kivy take care of the details. However, the line for the enter button is a bit tricky. To be honest, I hate this line of code. It’s very fragile. It calls self.parent to get the parent of the text input, which is a GridLayout, then calls .parent on that which yelds a BoxLayout (we’re navigating up through the orkiv.kv hierarchy here), and calls parent one more time to get the AccountDetailsForm. Then we can finally call the login method on that, to do the same thing as if we had clicked the login button. Thus users can enter their details, tab to the next box, and login without lifting their hands from the keyboard!

The reason I hate this line of code is that future changes in orkiv.kv could easily break it. If we decide to insert another Layout into the mix, this line will need to have another .parent added. If we decide to remove the surrounding BoxLayout and put the GridLayout as a direct child of AnchorLayout, it will again break. Worse, if we made such a change and ran the program, we might see that the new layout looked exactly as we wanted it to, but totally forget that we needed to test the tab-order widget.

There are other ways to get access to the AccountDetailsForm and its login method, but I’m not too keen on them either. We could call Orkiv.get_running_app().root. Or we could add an ObjectProperty to the AccountDetailsTextInput and set that property to point at the magic root variable. This latter is probably the most extensible, but it means that the Kivy Language file needs to be a bit uglier. I chose to stick with the .parent notation, but to include a comment to remind me that if I look at this section of code in the future, it would be ideal if I had an insight for how to implement it more elegantly.

Finally, we have the weird else clause which covers any case where the user has presed a key other than tab or enter. In that event, we just want the parent TextInput class to do what it would normally do; display the character in the text field on the screen. So we use the super builtin and pass it first the class we want to get the parent of, and the instance of that class, namely self. This returns basically the same object as self but as if it was an instance of TextInput instead of AccountDetailsTextInput. Then when we call _keyboard_on_key_down on that class, we get the default behavior for the class.

The rather arcane syntax of super is much simpler in Python 3, where we could just call super._keyboard_on_key_down The two argument syntax is still supported, as it is necessary to support a feature called multiple inheritance. That’s something I recommend you don’t learn about too early, not because it is a particularly complicated construct, but because it is, in my opinion, much less useful than it appears and you are quite likely to misapply it!

Oy gevalt, but that was a lot of explanation for not very much code. Luckily, you can probably figure out the changes to the Kivy Language file for yourself:

(commit)

Label:
    text: "Server"
AccountDetailsTextInput:
    id: server_input
    next: username_input
Label:
    text: "Username"
AccountDetailsTextInput:
    id: username_input
    next: password_input
Label:
    text: "Password"
AccountDetailsTextInput:
    next: server_input
    password: True
    id: password_input

We did two things to each TextInput here. First, we changed it to be an instance of the new AccountDetailsTextInput and second, we added a next attribute to each of them. This next points at the id of whichever input box it makes sense to be the next in the tab order.

But what about invalid logins?

Have you tried intentionally or accidentally entering invalid account details into this form and submitting it? The application dies outright, which is neither optimal nor friendly. Users are not infallible. In fact, users can be incredibly dedicated to totally breaking your fancy interface! Let’s try to anticipate some of their mistakes and supply an error message that makes a little sense instead of just crashing.

Let me tell you up front, this turned out to be harder than I expected! I don’t want to do anything too complicated for the intended audience of this tutorial. I ended up poking around in the sleekxmpp source code quite a bit to come up with this solution. I don’t like the results, but I saved it for you on a separate git branch. Too many tutorials pretend that the solution they present to you is the obvious one; instead, I want you to see that programming is often all about exploration and backing up and trying again.

The problem with the code I linked is that it locks up the interface so it’s hard to interact with. Since nothing can happen until connection has occurred anyway, I think it will be better to pop up a window that tells the user to wait while we perform the connection.
Before I show you the code, I want to describe how I was testing it as I developing it. I performed several different tasks and changed the code until all of them were working. This was time consuming (and the reason this tutorial is a little late) and tricky. Each time I changed things, I had to go through all the tasks to make sure that fixing one problem hadn’t broken other things. Often it had, which meant I had something else to fix and test. However, at the end of this section, you’ll be able to perform all these tasks with expected results:

  • Log into my personal jabber server and see the buddy list
  • Log into a throw away google account and see the buddy list
  • Click the login button without entering any details and get an error message to try again
  • Enter credentials for a host that does not exist and get an error message to try again
  • Enter invalid credentials for the google account and get an error message to try again

Let’s start by building a Kivy Modal View widget. A ModalView essentially sits in front of the other widgets, by default taking up the whole window, though you can make it look like it’s floating on top of the interface by giving it a size. How did I know this was the widget I wanted? I didn’t. I had to search through the Kivy API library for what I wanted. I first stumbled across the Popup widget, but it has extra features that we don’t want. However, I saw that it inherits from ModalView and that’s exactly what we need.

So we’re going to create a ModalView object that notifies the user that a connection is being attempted. If the credentials are invalid, it will give them a short message and invite them to return to the login widget and try again. If they are valid, it will print the Buddy List on itself. Let’s start adding this new class to the __main__.py:

(commit)

from kivy.uix.modalview import ModalView  # At the top of the file
from kivy.uix.label import Label

class ConnectionModal(ModalView):
    def __init__(self, jabber_id, password):
        super(ConnectionModal, self).__init__(auto_dismiss=False,
            anchor_y="bottom")
        self.label = Label(text="Connecting to %s..." % jabber_id)
        self.add_widget(self.label)
        self.jabber_id = jabber_id
        self.password = password

This is similar to what we did for the AccountDetailsForm above. We create a subclass of ModalView and initialize it with a jabber_id and password. We initialize the superclass, passing in a couple of arguments to tweak the behavior. We disable auto_dismiss because we don’t want the popup to disappear until we tell it to. Otherwise, it would disappear if the user clicked on it anywhere, even though it’s still trying to connect. We also supply anchor_y because ModalView inherits from AnchorLayout. When we add a button later, we’ll want it to pop up in front of the Label at the bottom of the screen. Notice how we are constructing a user interface in Python code here and that it’s rather bulky compared to the KV Language way of constructing an interface. However, since there’s only one widget for now and a second one created dynamically, it doesn’t really make sense to style this class in the KV Language.

We then construct a Label and add it to the Layout using add_widget. We store the reference to label on self so that we can update the text later. We similarly store the jabber_id and password.

Obviously, we aren’t constructing this widget anywhere, so it’s not going to be displayed if we run the code. Let’s rewrite the login() method to pop up this window instead of trying to connect. Note that if you were developing on your own, you might want to keep a copy of the current login() code in a separate buffer because we’ll be needing to adapt it to live in this new class, soon. Or you can just check your git history to see how the login method used to look. git show HEAD^:orkiv/__main__.py will show what it looked like in the previous revision. HEAD^ says “previous revision” to git. Yes it’s arcane syntax. You can see dozens of other ways to specify which revision you want to show in the git rev-parse manual.

Anyway, let’s display that popup in the login method:

(commit)

def login(self):
    jabber_id = self.username_box.text + "@" + self.server_box.text
    modal = ConnectionModal(jabber_id, self.password_box.text)
    modal.open()

We kept the one line from the old login() method which constructs the jabber_id. But now instead of connecting, we construct a ConnectionModal widget and instruct it to open itself. If you run this, it will no longer try to connect to jabber at all. Even though the connection code still exists on the Orkiv, that method is not being called. Obviously, calling that is the next step, but lets make tweak that connect_to_jabber method first to make it inform us when it cannot connect.

I didn’t notice the need for this change until later on when I was doing my own testing, but it’ll be easier to explain if we do it now. It’s common to do this when crafting commits in git (less so in Mercurial, which is an endless source of frustration for me). Instead of committing each piece of poorly thought out code as I go, I figure out what needs to be done and then design the commits so that they tell a coherent story to anyone that reads the history. If you read through the Examples committed on the github repo you can see each scene in this story as it is played out. It is much easier for you to understand than if I had committed each of my mistaken attempts in whatever crazy order that they occurred. When crafting git history, remember that there will always be a reader of your code and try to make the most elegant story possible.

Specifically, replace the single self.xmpp.connect() line with the following four lines:

(commit)

from sleekxmpp.exceptions import XMPPError  # At the top of the file

self.xmpp.reconnect_max_attempts = 1
connected = self.xmpp.connect()
if not connected:
    raise XMPPError("unable to connect")

There are actually two fixes here. I had to scour the sleekxmpp documentation to find the reconnect_max_attempts property. Without it, the client keeps trying to connect over and over and never fails. However, if we tell it not to bother trying to reconnect at all, for some reason, it fails to connect to gmail. So we allow it to reconnect once to keep gmail happy, but not indefinitely to keep our users happy.

Second, the connect() function returns a boolean value indicating whether the connection was successful. If it’s not successful, we want to communicate to whatever method called connect_to_jabber that it was unsuccessful. So we raise an exception that, handily enough, sleekxmpp has defined in their code. When we raise an exception, execution immediately stops in this method. However, we can catch the exception in the calling code. Let’s add that calling method to the ConnectionModal class now:

(commit)

from sleekxmpp.jid import InvalidJID  # At the top of the file

def connect_to_jabber(self):
    app = Orkiv.get_running_app()
    try:
        app.connect_to_jabber(self.jabber_id, self.password)
        self.label.text = "\n".join(app.xmpp.client_roster.keys())
    except (XMPPError, InvalidJID):
        self.label.text = "Sorry, couldn't connect, check your credentials"
    finally:
        if hasattr(app, "xmpp") and app.xmpp:
            app.xmpp.disconnect()

Notice that this method is called connect_to_jabber just like the one on the Orkiv class, but this one is attached to ConnectionManager. There is no law against reusing names if it makes sense to do so, as long as they are in a different namespace (the Orkiv namespace is completely independent from the ConnectionModal namespace). In fact, if you recall the consistency rant from Part 3, you will know that it is often desirable to do so.

We have a connect_to_jabber method on the ConnectionModal class that calls a totally different connect_to_jabber method on the Orkiv class. The latter method might raise either an XMPPError or an InvalidJID error. The former is raised explicitly if connected is False; the latter is actually raised inside the sleekxmpp code. Either way, it gets propagated up to the the ConnectionModal‘s method, where we catch it using a try...except clause. We also add a finally clause that checks if an xmpp property has been added to the app and, if so, disconnects it to keep it from freezing up the app, as we discussed in Part 3.

If you would like more information on exceptions, see the Python tutorial. There's also good coverage of Exception handling in my book, Python 3 Object Oriented Programming.

It only takes one line of code to have this connect_to_jabber called as soon as the ConnectionModal is opened. ModalView has a open event, so we just have to assign it a callable (any function or method, such as connect_to_jabber is a callable) that is called whenever that event is invoked. So hook this up as the last line of ConnectionModal's __init__ method:

(commit)

self.on_open = self.connect_to_jabber

There's one more thing I want to do. When there is a failure, instead of just showing a message and forcing the user to close the app, it would be much better if they had a way to go back to the login form. Let's add a button that allows them to try again. Clicking this button will hide the modal window and the original login form that was behind it will be visible so the user can edit the details. This can be done by replacing the contents of the except clause with the following code:

(commit)

from kivy.uix.button import Button  # At top of file

self.label.text = "Sorry, couldn't connect, check your credentials"
button = Button(text="Try Again")
button.size_hint = (1.0, None)
button.height = "40dp"
button.bind(on_press=self.dismiss)
self.add_widget(button)

Here we're adding more user interface in Python code and once again we see that it's bulky compared to the KV Language. We're still rendering the label, but we're also adding a button to the bottom of the window. We're giving it a 40 display pixel height, remembering to set size_hint to None in the y dimension so the layout knows to check the height. We then bind the on_press event of the button to the dismiss method (a callable, remember?) on ModalView. When the button is clicked, the modal disappears. Now it's much easier to test each of the failure conditions I listed earlier, one after the other.

Technically, this interface still freezes up when we connect, but it's less invasive since we're rendering a label instead of broken text areas. The correct fix would probably be to connect in another thread and then schedule interface updates using the Kivy clock, but that's a bit advanced for this tutorial.

Exiting gracefully

The last problem I want to address today is the fact that we disconnect as soon as we render the Buddy List. That's not going to be very useful when we get around to actually sending and receiving messages. However, not disconnecting causes the program to hang when we close the window because the xmpp object is sitting there doing it's job: waiting for incoming jabber messages.

We need to disconnect that object when the window closes. Luckily, Kivy gives us an event on the App class, named stop, that we can hook into to do just that. But let's arrange our code nicely.

I spend a lot of time rewriting code that I wrote before. Why? To make it more maintainable. I need the code to be readable in the future when I've forgotten what it does. Python is designed to be a very readable language, but that doesn't mean that it's self organizing. It's one thing to write readable sentences in English, but quite another thing to have a coherent and cohesive paragraph.

Even though it's temporary code, the hasattr call in our exception handler (which checks if the xmpp property has been added to the object or not) is a code smell. It would be better if the xmpp property always exists on the object and to check whether or not it is a valid value. So let's set that property to None by adding an initializer method to the Orkiv class:

(commit)

def __init__(self):
    super(Orkiv, self).__init__()
    self.xmpp = None

Let's also add a disconnect_xmpp method to the Orkiv class that does the necessary cleanup for us. This method will be called both when the app stops and when the login method fails (but not on successful login). It's a bit more involved than the dirty call to xmpp.disconnect() that we were making in our temporary code, because we want to be sure to get it right:

(commit)

def disconnect_xmpp(self):
    if self.xmpp and self.xmpp.state.ensure("connected"):
        self.xmpp.abort()
    self.xmpp = None

The conditional checks too things. First, it checks that self.xmpp is an actual object, and not None. If this check is False, python won't even bother with the second check, which is to see if the ClientXMPP object is connected. I had to actually look through the sleekxmpp source code to figure out how to check if it's connected using that weird state.ensure syntax. If xmpp IS connected, then we call abort(), which calls the disconnect() method we were calling earlier as well as some other cleanup tasks. Finally, regardless of whether it was connected, we set the xmpp property to None which both frees the memory used by sleekxmpp for garbage collection and puts the app in its known initial state in case we want to try to connect again.

While we're add it, let's hook up the stop event handler on the Orkiv. All it needs to do, for now, is call the method we just added:

(commit)

def on_stop(self):
    self.disconnect_xmpp()

You might be wondering why we have two methods, instead of just putting the disconnect_xmpp method body inside of on_stop. There are a couple reasons. One is that we're going to be calling disconnect_xmpp from a the exception handler in the next example. Of course, we could just call on_stop instead, but that wouldn't be as readable; the name disconnect_xmpp very clearly describes what the method does. Second, there is every chance that we'll later have to add additional code to the stop event handler to clean up other things when the app closes. By that point, we'll likely have forgotten that on_stop is being called from other places, and we may not want the new cleanup code to be called during the connection/login phase. Instant bug! It is often extremely worthwhile to use longer code if it is more readable than a shorter alternative.

Let's do that last step now: call the disconnect_xmpp method when login fails. We can remove the finally clause, since we no longer want to disconnect if login is successful. And we can remove the hasattr call, since that check is now being done more elegantly inside the disconnect_xmpp method itself:

(commit)

except (XMPPError, InvalidJID):
    self.label.text = "Sorry, couldn't connect, check your credentials"
    button = Button(text="Try Again")
    button.size_hint = (1.0, None)
    button.height = "40dp"
    button.bind(on_press=self.dismiss)
    self.add_widget(button)
    app.disconnect_xmpp()

More on maintaining history

That's it for coding in this part of the tutorial. I'm a bit concerned that the changes introduced in this tutorial were hard to follow, since we were making sweeping changes all over the file, but I wanted to describe them one at a time. If you're having trouble following it, you might have better luck looking at the individual git commits. If you select a commit, github will highlight the lines that have been added and removed in each change, making it easier to follow. It also allows you to see the entire file (there's a "View File" button) if you're feeling lost. I tried very hard to craft the changes in each commit as well as the commit message so that the history is very easy to follow.

You should try to do this yourself when you are developing. It is unlikely your history will be quite as readable as this repository (my real life repos certainly aren't!), because it is generally considered unwise to edit your history after you have pushed it to a public repository that other people have seen (think of trying to edit a published book after somebody buys it.) However, before you have pushed your changes, it is perfectly ok to rewrite and reorganize your commits so that they make the maximum amount of sense.

Git provides several tools for such work. One of the easiest to understand is the git commit --amend command. This command is like a regular commit, except that instead of creating a new commit with whatever changes you have prepared with git add, it alters the last committed patch to include those changes. It even allows you to edit the commit message! This is very useful if you make a commit and then realize you forgot to change something in that commit. For example, it's a terrific way to exclude useless, cluttering commits with messages like "Conform to pep8", "I forgot to remove a debugging statement", "Update documentation", or the most heinous commit message of all: "Blah".

Another really handy tool that I used extensively while developing this particular tutorial is git add -p <filename>. Because I didn't actually know exactly how my attempts with the ConnectionModal code were going to work out, I wrote and tested everything before writing the narrative. But then I wanted to commit only specific parts of what I had written in each example, each commit containing a single, coherent collection of changes. git add -p is an extended version of git add (the p is short for --patch) that loops over the changes in the file and allows you to interactively select exactly which hunks you want to go into the next commit. There are quite a few options you can use during each step; press the h to get an overview. Don't forget to call git commit when you're done!

Monetary feedback

If you liked the tutorial and would like to see similar work published in the future, please support me. I hope to one day reduce the 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 supporting me in one or more of the following ways:

Finally, if you aren't in the mood or financial position to help fund this work, you can always do your part to share it on your favorite social platforms.

Creating an Application in Kivy: Part 3

This article continues a series on creating a Kivy application. At the end of Part 2, we had a basic form for entering Jabber login details. In this part, we’ll hook up the login button to actually connect to the jabber server and download a Buddy List.

Make sure you’ve completed the previous two parts, or if you want to start from a clean slate, you can clone the end_part_two tag in my git repo for this project. Remember to do your own changes on a separate branch to avoid conflicts later.

git clone https://github.com/buchuki/orkiv.git # or 'git pull' if you've cloned before and want to update
git checkout end_part_two
git checkout -b working_changes
source venv/bin/activate

Table Of Contents

Here are links to other parts of this tutorial.

  1. Part 1: Introduction to Kivy
  2. Part 2: A basic KV Language interface
  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

Handling Events

Dictionary.com defines an event as “something that happens, esp. something important”. That’s a perfect description of events in Kivy. Kivy is firing events all the time, but we only have to pay attention to those that we consider important (in the upcoming example, clicking/touching the Login button is important). Every graphical toolkit I have ever used has some concept of events. The difference between Kivy and those other toolkits is that in Kivy, event dispatch and handling is sane and uncomplicated.

If an event is something that happens, then an event handler is something that reacts when an event occurs. Our event handler will eventually log into the server and display the Buddy List, but lets start by printing a quote from a humorous scene in the film Rush Hour. We do this by adding a method to the AccountDetailsForm class in __main__.py:

(commit)

class AccountDetailsForm(AnchorLayout):
    def login(self):
        print("Click the goddamn button")

Remember in Part 1 I mentioned that object oriented programming allowed us to add functionality to existing classes? That’s what we are doing here. The AnchorLayout class has no idea what it might mean to “login” to something, but it makes sense for AccountDetailsForm to do so. So we add a method to the subclass named login. A method is just a function that is aware of which object it is attached to (that’s why it has the parameter self). At this point, we don’t care what object we are attached to, but it will become important soon.

So that method, which we named login, is an event handler. Actually, technically, it’s just a method that happens to handle an event, and we will hook it up by calling that method from the true event handler. Let’s do that next. We just need to add one property to the login Button in our orkiv.kv file:

(commit)

    Button:
        size_hint_y: None
        height: "40dp"
        text: "Login"
        on_press: root.login()

Kivy is really really good about making programmers do the minimal amount of work required. If you add this one line of code and run it, you can click the Login button repeatedly, and each time, the movie quote will show up on the terminal.

The Button widget in Kivy has a press event. The key to signifying an event handler is to add an on_<eventname> property. Now this is where the KV Language gets a little creepy. The code that comes after the event handler property name is standard Python. In fact, you could just use on_press: print("you clicked it") and it would work. Or if you wanted multiple lines of Python, you could put them on the next line, indented, as though the program code was a child widget.

Don’t ever do that. That’s my rule: never have two or more lines of python logic in a KV Language file. When you break this rule, make sure you know for certain that you have a good reason to do it and that you thought that reason all the way through. This will aide you in the future if you ever want to change the layout without trying to sift out the business logic that hasn’t changed. In my mind, the point of KV Language is to define layout and style. You should not mix logic (program code) with the styling. Instead, put the program code on the class in __main__.py and use one line of logic to call that method.

There’s a small amount of magic going on here. The root variable in a KV Language file always refers to the object that is at the left-most indent in our current block. In this case, it’s the <AccountDetailsForm> class, which is the class containing the handy login method. KV Language has two other “magic” variables that you may find useful: app and self. app can be used anywhere in a KV Language file to refer to the object that inherits from Application; so the Orkiv object. Self refers to the current widget. If we called self.x() in the on_press handler, it would refer to the Login Button object itself.

Interacting with widgets

Now, let’s figure out how to get some values out of the textboxes in the form. To this end, we’ll need to refer to objects in the KV Language file from inside the associated class in our __main__.py. This requires a few sets of changes to both files. Let’s start with some minor additions to the elements of our form in orkiv.kv.

(commit)

    Label:
        text: "Server"
    TextInput:
        id: server_input
    Label:
        text: "Username"
    TextInput:
        id: username_input
    Label:
        text: "Password"
    TextInput:
        password: True
        id: password_input

We’ve simply added an identifier to each of our TextInput boxes so that we can refer to them elsewhere in the code. Note that I gave them all consistent names ending in _input. Consistency is very important in programming. Your memory is not infallible, and it would be silly to overtax it by trying to remember that one box is named password and the other is named UserNameTextInput. After years of programming, this statement seems blatantly obvious to me. However, I am frequently frustrated by non-developers who supply (for example) csv files that use spaces and underscores interchangeably or vary the capitalization of identifiers that I need to sanitize before using in program code. Do yourself and everyone else who works with your code a favor and strive for consistency. One really good way to do this in Python code is to strictly follow the Python Style Guidelines even if you disagree with some of the rules. I strongly recommend using a pep-8 highlighter in your editor (I personally use SublimeLinter) to aid you in this pursuit.

Ok, back to the code! The key takeaway is that by giving these widgets an id, we can reference them in other parts of the KV Language file. Specifically, we can set them as the values of custom properties on the AccountDetailsForm class rule like so:

(commit)

<AccountDetailsForm>:
    anchor_y: "top"
    server_box: server_input
    username_box: username_input
    password_box: password_input
    BoxLayout:

We have defined three custom Kivy properties (named server_box, username_box, and password_box) on the AccountDetailsForm class. Each of these properties is assigned a value of the id of one of the text boxes.

It is common to name the properties the same as the ids on the boxes they point to (see my diatribe on consistency above!). However, I chose not to do that here for pedagogical reasons; it’s clear from this example that a property name is a completely different thing from an identifier.

This is no different from setting a property that is meaningful to the parent class such as anchor_y.The difference is that the parent class (AnchorLayout) doesn’t know about them. Neither does the child class, yet, but we’ll now fix that in __main__.py:

(commit)

from kivy.properties import ObjectProperty  # at top of file

class AccountDetailsForm(AnchorLayout):
    server_box = ObjectProperty()
    username_box = ObjectProperty()
    password_box = ObjectProperty()

We added an import statement so we can access Kivy’s ObjectProperty class. Then we specified three instances of this fancy property on the AccountDetailsForm. These instances must have the same names as the properties defined in the KV Language file, since they are referring to the same thing. When the class is constructed, these three properties are defined as having values of None. However, as part of the KV Language parsing process, Kivy applies the styling found in orkiv.kv and overwrites those None values with the three values we specified in the previous example.

So we have widgets that are named by ids in our KV Language file that are being assigned to properties by the same KV Language file that are defined in the __main__.py file. Got that? The upshot of this slightly convoluted pipeline is that we can now access those values inside the login method on our class:

(commit)

    def login(self):
        print(self.server_box.text)
        print(self.username_box.text)
        print(self.password_box.text)

If you run the code now, you should see the contents of the login form boxes displayed on the console when you click the Login button.

Choosing client libraries

Let’s take a break from programming and talk about something that has been overlooked in every programming textbook and tutorial I have ever read: How the hell do you figure out how to do what you need to do?

The short answer, as with every question asked in the last decade, is “Search Google!” (or rather, a search engine that doesn’t spy on you, such as Startpage.com or Duck Duck Go). That always brings out the more salient question, “what do I search for?”.

If you’ve recently started learning to program, you might be under the impression that programming is mostly about connecting loops, conditionals and data structures into some meaningful representation of an algorithm or design pattern. That’s certainly a major part of the job, but often, programming involves reusing existing code and connecting it. Software development is often more like building a lego set where you get to use a variety of prefabricated bricks that do almost exactly what you need, and then using contact cement to glue on some custom-built parts that don’t come with the lego set and can’t be found on store shelves.

Anyway, at this point we have a login form that we can enter details in and do something when the button is clicked. But we aren’t doing what we want to do, which is to display a buddy list for the given XMPP account. How can we do that?

Well, one option might be to read through the Jabber Protocol Specification and implement all the Jabber commands one by one. But that sounds like a lot of work. The absolutely most important attribute in a good programmer is laziness. This means spending hours to automate boring things so you never have to do them again. It also means spending extra time now to write your code in such a way that you or a coworker can reuse it in the future. Finally, it means taking advantage of other people’s work so you don’t have to redo it.

Most common tasks have been collected into what are called “libraries”. Kivy itself is a sort of library, a library for creating kick-ass graphical interfaces. Often when faced with a “how do I do this?” question, the next question should be “Are there any existing client libraries that I can use?” Imagine if you had to manually set the value of each pixel on the screen in order to render a button or textbox, and then process individual keypresses directly to find out what was in a text input box!

Before I started writing this tutorial, I wanted to make sure there was a client library I could use to connect to Jabber. I did a web search and found several options, best summarized by this question on Stack Overflow. Stack overflow is a great place to search for answers; if you can’t find what you are looking for, you can even ask the question yourself!

If a web search yields a nice collection of client libraries that might solve your problem, the next question is, “which one do I use?” The answer is to visit the home pages for each of the libraries and ask yourself questions like these:

  • Is the license compatible with the license I want to use for my application?
  • (If not open source) How much does it cost to license the library?
  • (If open source) Does the source code for the library look well maintained and easy to read?
  • Does the library appear to be actively developed and has there been a recent release?
  • Is there an active user community talking about the library?
  • Does the library appear to have useful (readable, up-to-date, complete) documentation?
  • What avenues of support do I have if I have trouble?
  • (If Python) Does it boast Python 3 support?

After some amount of research, I ended up choosing Sleek XMPP as it seems to have a modern, usable application programmer interface, reasonable source code and documentation, and a permissive license.

At this point, you’ll want to install SleekXMPP and it’s one dependency. Make sure the virtualenv is active and then issue the following command:

pip install sleekxmpp dnspython

Figuring out how to use a client library

The next step is making yourself familiar with the client library so you know what functions and methods to call to create the desired behavior. This depends entirely on the documentation for the library. I personally like to start coding as soon as possible and see what breaks. Then I refer to the documentation and figure out why it broke and evaluate how it needs to change. In the case of SleekXMPP I started exploring the documentation until I could answer the question, “What is the simplest possible command-line application I can use to retrieve a buddy list?”. This is it:

(commit)

import sleekxmpp, sys

xmpp = sleekxmpp.ClientXMPP(sys.argv[1], sys.argv[2])

xmpp.connect()
xmpp.process()
xmpp.send_presence()
xmpp.get_roster()
print(xmpp.client_roster.keys())
xmpp.disconnect()

This script isn’t part of orkiv, it’s just some playing around I did before trying to integrate this collection of method calls into Orkiv. It took me about 20 minutes to come up with these few lines of code, mostly because the SleekXMPP documentation is a little rougher around the edges than I anticipated. I first implemented a couple of the tutorials in the Quickstart and got them working. However, the examples seem to use a verbose inheritance structure that seems quite unnecessary to me. So I tried to extract the guts into the procedural example you see above.

I do my testing inside a running Python shell — just type python and you can start entering python commands right into the interpreter. I personally use IPython as much as possible, because its shell is so much nicer to use than the standard one. At first, my call to get_roster() was returning an error; this was because I hadn’t noticed, in dissecting the inheritance structure, that I had to call connect() first! However, after my trial and error phase were completed, I came up with the above code, which I saved as sleekxmpp_buddylist.py and tested using python orkiv/sleekxmpp_buddylist.py jabberid@jabber.org password. I tested it with a throw-away Google account and my own personal jabber server. Works like a charm!

The script itself first imports a couple modules and creates a ClientXMPP object, passing in the username (in the form “username@server.tld”) and passwords from the command line. Then it calls several methods on this object to do some jabbery stuff. Then I output the value of the roster (“buddy list”), and disconnect.

Printing a buddy list on login button click

We could just copy the code above into the login() method and modify it to use the jabber id and password we got from the form. However, that would be rather short-sighted. We know we’re going to need to keep this ClientXMPP object around longer than a single button click, and indeed, longer than the lifetime of the login form. So instead, lets add a method to the Orkiv application object itself:

(commit)

from sleekxmpp import ClientXMPP  # at the top of the file

class Orkiv(App):
    def connect_to_jabber(self, jabber_id, password):
        self.xmpp = ClientXMPP(jabber_id, password)
        self.xmpp.connect()
        self.xmpp.process()
        self.xmpp.send_presence()
        self.xmpp.get_roster()

That’s a pretty simple method that creates an xmpp attribute on the app class and runs the boilerplate code for connecting to jabber, as we discovered in the script above. Of course, this method won’t actually do anything if we don’t call it from somewhere. The obvious place to do that, of course is when we click the login button. The correct thing to do will be to connect to jabber and then render a buddy list in the window, but we’re running out of space, so let’s just print it to the console:

(commit)

def login(self):
    jabber_id = self.username_box.text + "@" + self.server_box.text
    password = self.password_box.text

    app = Orkiv.get_running_app()
    app.connect_to_jabber(jabber_id, password)
    print(app.xmpp.client_roster.keys())
    app.xmpp.disconnect()

Once again, the method is quite simple. We first grab the jabber id and password from the form box, being careful to concatenate the username and server to generate the jabber id. The next line, where we get the running app may require some explanation. We are calling a function on the Orkiv class itself. Remember, a class describes an object, so we aren’t talking to an instance of that object here, just to the class. When a method is meant to be called on a class instead of an instance of that class, it is called a static method. In this case, the static method happens to return an instance of the class: the currently running app. Normally, there is only ever one running app in a Kivy program. In fact, you’d have to be both foolish and audacious to get more than one.

The other slightly tricky thing about this line is that we have not defined any get_running_app method on the Orkiv class. In fact, we only have one method, connect_to_jabber. But remember that Orkiv inherits functionality from the App, and indeed, App has a get_running_app static method. That’s what we’re calling here.

Once we have access to the active app object, it’s easy to print the roster and disconnect. Obviously, it wouldn’t make sense to disconnect immediately after login in a completed jabber client. However, if you don’t disconnect and test this, the program won’t stop running when you close the window; it leaves the xmpp object hooked up in the background trying to do the kind of stuff that jabber clients do. When I tried it, I had to force kill the process with kill -9.

It is common, when coding, to do temporary things like this to test the program in its current state. We know we’ll remove that line in part 4, but… well, truth be told, part 4 hasn’t been written yet! In part 4, we’ll deal with some annoyances with this form, like the fact that we can’t tab between input fields, that we have no idea what happens if we provide incorrect login details, and that pesky problem of the jabber staying alive after we closed the window.

Monetary feedback

If you liked 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 supporting me in one or more of the following ways:

I’d particularly like to advertise Gittip, not for my own financial gain, but for everyone. I think a world where people are able to use gittip for their primary source of income is a world worth striving for. Even if you don’t choose to tip me, consider tipping someone, or if you are a producer of knowledge or art, market your own products and services through the generosity system.

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

Creating an Application in Kivy: Part 2

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.)

git clone https://github.com/buchuki/orkiv.git
git checkout end_part_one
git checkout -b working_changes
source venv/bin/activate

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 __main__.py:

(commit)

from kivy.uix.boxlayout import BoxLayout


class AccountDetailsForm(BoxLayout):
    pass

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:

(commit)

AccountDetailsForm:

<AccountDetailsForm>:
    Label: 
        text: 'Hello World'
    Label:
        text: 'Another World'

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:

(commit)

<AccountDetailsForm>:
    orientation: "vertical"
    GridLayout:
        cols: 2
        Label:
            text: "Server"
        TextInput:
        Label:
            text: "Username"
        TextInput:
        Label:
            text: "Password"
        TextInput:
            password: True
    Button:
        text: "Login"

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:

example_6

Restricting sizes

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

(commit)

<AccountDetailsForm>:
    orientation: "vertical"
    height: "200dp"
    size_hint_y: None
    GridLayout:
        cols: 2
        row_default_height: "40dp"
        row_force_default: True
        spacing: "10dp"
        padding: "10dp"
        Label:
            text: "Server"
        TextInput:
        Label:
            text: "Username"
        TextInput:
        Label:
            text: "Password"
        TextInput:
            password: True
    Button:
        size_hint_y: None
        height: "40dp"
        text: "Login"

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:

example_7

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!

Creating an Application in Kivy: Part 1

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!

  1. Part 1: Introduction to Kivy
  2. Part 2: Creating a Form
  3. Part 3: Handling Events
  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

Prerequisites

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 Dependencies

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:

mkdir orkiv

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
it’s working:

(commit)

print("hello world!")

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 print statement from our __main__.py and replacing it with the most basic possible Kivy application:

(commit)

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 orkiv/orkiv.kv:

(commit)

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:

  1. Ends with the .kv extension
  2. 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 App.

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.

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!

Arch Linux Community on Gittip

I’d like to invite members of the Arch Linux community to join the new Gittip Community I set up for Arch Linux. Communities are a great idea that helps make Gittip more global and more local at the same time.

Gittip is a platform to use generosity to crowdfund kickass content creators, from musicians to artists authors (like me) to developers like these. The communities feature allows us to see what other Archers are doing for their distro.

I want to strongly encourage our developers, Trusted Users, and even the retirees (including me) to join the community so we can start funding you. As Arch Schwag maintainer, I — perhaps more than anyone — know just how generous this community is with both their time and their money. Let’s start sharing our money with those users who are willing to share their time with us.

Arch devs are a pretty humble bunch, for the most part who might not think they deserve funding. So please encourage them to set up gittip profiles so that we can tip them. Over time, I hope some of them will be earning enough from gittip to take some time from their day jobs and help Arch improve at an even faster, bleeding edge pace.

Finally, I’d like to note that Chad Whitacre, founder of gittip has mentioned a plan to support funds, a way to tip entire organizations or communities such that the funds are distributed by the crowd. When this is implemented, I intend to donate Arch Linux Schwag income to this vessel, rather than through the Arch Linux donations page, as I have done for years. The Arch Schwag funds are not actually terribly useful to the project, aside from offsetting server costs and the like. I believe that tipping our developers directly will be much more beneficial to the project. Indeed, I can imagine the Arch Linux team funneling some of the donation money back into the gittip community in the future.

Arch Linux Laptop Sticker Price Reduction

I recently ordered a new batch of Arch Linux laptop stickers. However, because they have been selling so well, I ordered three times the number that I usually stock! I was able to get a much better price by ordering a larger bulk quantity and I’m excited to pass the savings onto all the loyal Arch Linux users out there.

The price for a single Arch Linux Sticker has dropped from $1.90 to $1.35. The savings are even greater if you purchase in bulk; you can now order 20 stickers for 80 cents a piece!

Arch Linux Laptop Sticker

Head over to schwag.archlinux.ca to order your stickers and other Arch Linux goodies. If you’re interested in more generic Arch Linux branded items, check out our Zazzle shop.

Next Year: addressing the more subtle sexism at Pycon

From a gender equality point of view, I’d call Pycon 2013 a success, though perhaps a better word is “progress”. The gender ratio apparently doubled to 20% this year. If that continues (depending if it’s a constant, linear, or quadratic curve) we could be at parity in as little as two to three years.

Another indicator of forward momentum is that women this year were able to behave, to use a sexist term, “like women,” without fear of reprisal. That is to say, I saw makeup, heels, and skirts, and they did not seem out of place. This is not to suggest that women should or must dress up to attend conferences; the traditional vendorware is equally acceptable for all genders. However, it is progress that more women felt they had a choice in the matter and did not feel an obligation hide their physical differences. I think the fact that there was more variety among the male dress styles is also a sign of success.

The worst charges coming out of Pycon 2013 were the use of inappropriate jokes. To the best of my knowledge, there were no reports of women being harassed, assaulted, or groped during the conference. I’m not aware that this has been an issue at past Pycons either, but I think it’s a sign that the Python community is better behaved in this regard than some of her sister tech conferences.

So all in all, while it wasn’t completely successful, Pycon 2013 was a terrific step on the road to eliminating sexism and creating gender equality. Let’s make next year an equal sized step. Here are a few topics I think we, as a community, can work on to engender further progress.

I’m going to start with a couple links. Ruth Burr wrote a terrific essay titled Things You Think Aren’t Sexist, But Really Are a couple weeks ago. In summary: Men, you are instructed to go to conferences to network and interact, not to date or hook up.

Yes, you might meet the love of your life at Pycon, but don’t expect, intend, or plan for that to happen (at PyCon or anywhere). Behave professionally, and consider each woman you meet for her knowledge and intelligence, not her figure or her marital status, just as you would when interacting with a male.

Ned Batchelder, with his amazing talent for understanding and explaining problems wrote another great article on the root issues. Summarized, he says friction is inevitable, and that education is better than shunning when people make mistakes.

I started planning this article while attending Pycon this year. I had to scrap those plans after the so-memed “donglegate” fiasco. I don’t have anything to add to that discussion, but as Ned illustrated, there were many many instances of similarly inappropriate comments at Pycon. I myself made such a joke, most of my friends did so, I overheard a conference organizer say something inappropriate. This is not sexism per se, but sexual and other potentially offensive comments need to be reduced. Comments laced with sexual innuendo do not belong in a professional or a family setting, and Pycon is intended to be both.

Let’s start with interation between the genders. In her article, Ruth Burr mentioned that women can feel awkward when they interact with men because the men assume they are flirting rather than interested in the topic at hand. Many men see cleavage and assume the speaker can’t possibly know as much as them about whatever topic that is. Some girls avoid interacting with men because of this awkward sensation, and if they do, the interactions are tainted.

I had a related problem. While I comfortably talked to men of varying skill levels at Pycon, I felt uncomfortable addressing women because I was afraid of sending some vibe that I was being flirtatious. So I tended to ignore the female attendees. This is unfortunate for everyone who missed out on that potential conversation. Pycon 2014 needs to increase the interaction between the genders, not just the attendance ratios. Ladies, talk to the shy guys, they need to be taught that you aren’t that intimidating. Guys, talk to the women, they need to learn that we are interested in what they have to say about tech, and not their figures. As it stands, only the sexist guys are interacting with the women, and it makes us all look bad.

The gender ratio really fell during the developer sprints. I don’t think there were any female sprint leaders presenting projects to hack on. Worse, I’d estimate between one and two percent of the sprint attendees were women. This is a huge area for improvement. To the various diversity groups out there, please encourage your members to stay an extra day or two and attend the Pycon dev sprints. Get them involved with Open Hatch if they are unsure how to contribute to open source projects. Sprint leaders, make sure female attendees are welcome, especially if they are new coders (indeed, make all new coders welcome).

I noticed a lot of Impostor syndrome among the female attendees and speakers. Programming really is easy. The fact that you enjoy it and find it quite simple is not a sign that you don’t know the “hard stuff” and therefore you’re not a “real programmer.” Quite the reverse, in fact. It’s not necessary to apologize for your lack of knowledge if you’ve been invited to do a talk or are about to join an open source project for the first time. Find ways to build your confidence (contributing to open source and getting feedback is a great start), and start believing in your skills. Even if you don’t believe it yourself, try to project confidence in your coding abilities; it will send a much more effective signal that women are capable and here to stay. Don’t worry if you over-present yourself; faking your way through it is a great way to find out that you’re actually better than you thought!

I’d like to close with an admonishment to those people who open their articles on sexism with a discussion of their gender. These usually take one of two forms: the disclaimer and the shocker. The disclaimer is most often used by men and sounds like, “I am a privileged white male so I don’t understand what it’s like for women, but I still think I have something valid to say on this topic”. The shocker is used by both genders and sounds like, “I am a man/woman, so you’re going to be amazed that my opinion on this topic is different from other members of my gender.” Yes, it is useful to state your bias and frame of reference. However, be cautious that your purpose in doing so is to remove distortion from the lens you are applying to the discussion, not to add to it.

And now, feel free to analyze my bias in this article. I am a privileged white male from a blue-collar family. I’ve had many amazing opportunities in the tech industry. I have very little experience as the target of discrimination, outside my mental illness. My interest in feminist issues comes from my sister’s master’s degree on the subject; I proofread most of her undergraduate and graduate level essays, and gained a relatively deep understanding of the topic. I acknowledge that I am a racist, sexist jerk by culture and conditioning. Sometimes I forget to compensate for that. I find it exceptionally easy to overlook the patriarchy when it’s doing me favors, and I will never be as keenly aware of its negative impact as someone who is directly experiencing it every day.

Guido Van Rossum Should Retire (and focus on python)

At the two previous Pycons I’ve attended (2009 and 2012), Guido Van Rossum’s keynotes sounded bored and uninterested, even though the content was meaningful. I was actually wondering if this would be the year that he would step down from BDFL of Python. Thankfully, I was dead wrong.

Instead, he presented a highly technical and very exciting addition to the Python language. Alfredo told me this started when he took a month off between stepping down at Google and starting at DropBox. Now, when normal people take a month off, they relax or travel or visit friends and family. Not our BDFL. He writes a callback-free asynchronous event loop API and reference implementation that is expected to massively alleviate Python’s oft-maligned lack of a consistent, unhackish concurrency solution.

Let’s have more of that. What if Mr. Van Rossum could hack on Python full time? Would we see quantum progress in Python every month?

Anyone who knows about the Gittip project likely thinks they can guess where this is going. We, the people, can each tip our BDFL a few cents or dollars per week so he can focus on whatever he deems worthy. It’s safe to assume that a man who spends his vacation time drafting a new Python library would choose to work on Python full time if we funded him.

This plan is great, and I actually think that Guido could easily earn enough to quit his day job if he endorsed Gittip and invited individuals to tip him. But I’d like to discuss a different plan: Not individuals, but companies should tip Guido the maximum gittip amount as a sort of “partial salary”. At $1248 per year, most companies wouldn’t even notice this expense, and they would get a better programming language and standard library in return. The rate of accelerated development would be even higher if each of these companies chose to invest an entire salary, split between a hundred Python core and library developers. If a hundred companies chose to do this, those hundred people could work on Python full time. The language and library would improve so vastly and so rapidly that the return on investment for each of those companies would be far greater than if they had paid that same salary to a single developer working on their in-house product, full time.

It might take some convincing to justify such a strategy to these corporations. Companies tend to like to know what is happening to their money, and simply throwing a hefty developer salary at Gittip would be hard to justify. Obviously “goodwill” could support some of it, in the same way that so many companies sponsored Pycon in exchange for exposure.

Cutthroat CEOs should perhaps consider not just the value that having Guido working exclusively on Python is, but also the cost of having him work for the competition. I’m sure Box.com CEO Aaron Levie was a little nervous when he found out that the first and greatest Python programmer of all time had recently hired on at a major competitor. Perhaps Box.com can’t afford to steal Guido from Dropbox, but if all the companies currently involved in cloud storage were to tip Guido $24 per week on Gittip, this incredible programmer could be working on an open source product that directly and indirectly benefits their company rather than improving the competing product on a full-time basis.

Most of the arguments that Gittip will fail are based on the premise that not enough money can be injected into the platform to sustain full time development by open source programmers. However, if an open and caring relationship can be built such that the corporate world is also funding the system, I think it can become extremely successful. Everyone will benefit: Open source projects will improve at a rapid pace. Exceptional developers will get to pursue their passions. End users will get better products. The overall level of happiness in the world will be higher.

I would like to see a world where brilliant young software engineers are not risking their mental health (and consequently, their lives) on startup ideas in the hopes of being bought out for a few billion dollars. I would like to see a world where those engineers are not working for large corporations that have neither their employees nor their end users (but rather, their stockholders and advertisers) interests at heart. I would like to see a world where those developers can choose to invest their passion in open source products that will change the world.

My Android phone no longer has a Google account

This week, I was finally able to fulfil a longstanding goal: to delete my Google account from my Android phone. This is a step in a series of progressions towards “completely” disappearing from Google’s radar. I have been comfortable with the state of my laptop, which avoids all Google spyware using ghostery to block Google analytics, disabling cookies on all Google domains, and using Startpage.com for search. I’ve dropped Google Talk in favour of a jabber server hosted by a friend. While I still actively monitor my Gmail account via IMAP, it is not my primary address and is largely only used for correspondence that is already public, such as mailing lists and Google Groups.

The three things that I have still been using Google for were:

  • Maps
  • Paid Apps From Google Play
  • Contact Backup

I still use Google maps on occasion, though my main navigation equipment is an offline Garmin GPS device that — to the best of my knowledge — is not notifying anyone of my location at any time. I largely addressed the other two issues this past week.

I recently received my Cubieboard in the mail. It’s basically a specced up Raspberry PI. I installed Arch Linux by following the instructions at this thread.

I then set up Own Cloud by following the instructions at the Arch wiki. Once it was set up, I realized that I personally don’t have much use for calendar sync or file sharing, but that the contact backup was crucial. I didn’t want a full LAMP stack running on my little ARM processor, so I uninstalled Own Cloud and set up Radicale instead. Now my phone’s contacts are backed up and I no longer need my Google account to support that feature.

Then I was notified that AOKP, my current Android ROM of choice, had released an update. I thought “Hm, I wonder if I can get away with not installing the Google Apps package at all.”

I couldn’t. But I tried. The main issue is that there are two paid apps in my Google Play account (SwiftKey and SwipePad MoreSpace) that I do not want to live without, and do not want to purchase again from another vendor. In the case of SwipePad, I couldn’t even find another vendor. I toyed with backing up and restoring the .apk’s, but I got certificate and signing errors. I’ve read that these can be circumnavigated with Titanium Backup, but I haven’t gotten around to trying it yet.

So I installed Google apps and reluctantly activated my Google Account to install these two paid apps. Then I disabled my Google Account.

I then installed Aptoide to replace Google Play. It had recent versions of all the free apps I use on a regular basis. It looks like it will be able to supply my app needs into the future.

I have logged into my Gmail account and deleted my pre-existing contact list. This means that even if I do have to enable Google Play in the future, I will no longer be spammed with “Your friends like this app” messages. It also means Google will not be able to track my future relationships unless they are with people who use Google services.

Now if only Ghostery and Firefox would get Ghostery working on Android, I’d actually feel safe using my device!