ObjectList tutorial

This blog post will give you an introduction to the ObjectList widget which is a part of the kiwi library.

* Rationale

Creating graphical user interfaces which displays a sequence of objects is a common task. In the GTK+ toolkit you will normally use a GtkTreeView for this. GtkTreeView is a very flexible and extensible widget, for instance it allows you to separate the data storage from the representation. However the disadvantage of using the GtkTreeView is that it’s a little bit too complicated to use, especially for beginners.

The ObjectList aims to provide a familiar API to create, manipulate and access sequences of objects. It builds on top of GtkTreeView, and allows you to access the “raw” objects (view, columns, model, cellrenderers, selection) in case you want to do something which is not directly supported by the ObjectList.

Kiwi and ObjectList are tied to the Python programming language and depends heavily on PyGTK (and thus CPython). However the concepts introduced in the widget are usually not specific to Python, it’s very possible to implement similar high level wrappers on top of GtkTreeView for C#, Java etc.

* Simple ObjectList example

Here is the source code and the output of a simple ObjectList example

Simple ObjectList example Simple example screenshot

Let’s walk through the example and explain what it does.

  • The class Fruit is defined with two attributes; name and price.
  • An ObjectList called fruits is created which has two columns, name and price
  • 5 objects are created and inserted into the list.

The example is concluded by creating a PyGTK window, adding the objectlist to it and running the main loop.
The data displayed in the ObjectList is stored in normal python instances, there is no need to create and set column types for a GtkTreeModel and extract the data from your python objects and insert it into the model. The model / view separation is kept while still keeping it easy to use.

Notice that the data is appended to the list by calling the append() method of the ObjectList, this is intentionally similar to the append method of the builtin list type of python. If you wanted you could use the extend() method to insert a list of object at one go.

The objects inserted into the list can be modified by using standard python list concepts:

  • iteration: for item in list
  • accessing an individual item: list[n]
  • removing an item: del list[n] or list.remove(item)
  • accessing parts of the item: list[n:m]

There are also methods beyond a normal python list routines which only makes sense in graphical interfaces:

  • selecting an item: list.select(item)
  • getting the selected item: list.get_selected()
  • changing the columns: list.set_columns(columns)
  • getting the columsn: list.get_columns()
  • etc…

* Columns

When you create a column you define how the data is going to be displayed. Column width, sorting, justification, markup and so on. Here is an incomplete list of the support column attributes:

  • title: the text will be used in the column header
  • justify: the justification, eg left or right aligned
  • format: printf style format string
  • width: width in pixels of the column
  • sorted: if we should sort the data after the content in this column
  • editable: is the column editable?
  • use_markup: should the content be interpreted as markup?
  • use_stock: treat the content as stock icon names and display icons

Here is a more complicated, real world example from Stoq, a Retail Management System written on top of Kiwi.

Accounts payable column definition

Accounts payable

The interface shows the accounts payable application which lists outgoing payments.

What we can see from the screenshot is:

  • The first column is sorted and it has the title “#”
  • The third column is the supplier name which is a bit too wide to fit and uses ellipsize
  • The fourth column is the date the purchase was sold and is formatted according to the current locale
  • The last column uses the special datatype currency which formats a number according to the monetary rules defined for the current locale, with thousand separators, decimal points and currency symbols set right.

This is all for now, for more information about Kiwi check out Howto, the API reference and the source code repository

This entry was posted in Blogroll, General, GNOME, olpc, PyGTK, Python. Bookmark the permalink.

4 Responses to ObjectList tutorial

  1. Anders says:

    This doesn’t seem to be very MVC friendly? How about using GtkListStore instead? Maybe one of the Tinymail iterators can be helpful here.

  2. Nice!

    Some questions/remarks:

    – it would be good if you had a link to the working example to download – the sample code you give here on its own is not enough to run it.

    – the ObjectList API doc has an example, and then mentions that when you run it it won’t actually show anything. I didn’t understand what it was trying to say, and cutting and pasting the code then running it did in fact show something for me.

    – how can you update the model ? How does that trigger the view to update ?

    – is there a way you can still filter the view ?

  3. johan says:

    Thanks for the comments;

    I added a link to the example directory, just click on the code screenshot.
    You should also find examples in the package, tarball or svn checkout.

    I’ll look into updating the doc string to show something more sensible.

    You can update the row references by model by doing; list.update(model).
    It would be possible to write a model which automatically propagates the updates to the view, it just that I never gotten around to do that.

    There’s no way to filter the results at the moment, the ObjectList was designed to be used by database applications where it’s fairly cheap to regenerate the results. I believe it should be possible to use a filter model with some minor tweaking, do you have a good use case for that?

  4. Well, I was thinking of writing a simple GUI for the Getting Things Done app I’m using and possibly doing it with kiwi. So I want a treeview showing all the tasks, with columns for title/category/context/flags, but I’d like to be able to have a dropdown box at the top for each of them so I can quickly filter by category/context/flags. Does that make sense ?

Leave a Reply

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