I often end up reading code using GtkListStore in Python, either in existing projects or on irc when someone asks me to fix their program. It’s pretty straight-forward to using the GtkTreeModel interface and it’s various implementations such as GtkListStore and GtkTreeStore. However, due to lack of proper documentation, the small pieces of Python sugar on top of the raw C wrappers is seldomly used. In this blog post I will attempt to document the most useful one in hope that some popular search engines will pick this up and help someone in the future.
Construction
For starters, let’s look into construction of GtkListStores:
model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_INT, gobject.TYPE_FLOAT)
This creates a liststore with three columns, a string, an integer and a float. The column types are specified using the constants available in the gobject python module. Since I’m hardly a normal person, I’ll immediatelly get frustrated when I see that kind of code. Instead, I wish people could write the following code instead, which is shorter and thus easier to parse:
model = gtk.ListStore(str, int, float)
It does exactly the same things, interally str is mapped to the gobject.TYPE_STRING constant and so on.
Appending data
At some point during the life time of a program you want to insert data into a model. A common way of doing is that is
the following:
iter = model.append()
model.set(iter, 0, “foobar”)
model.set(iter, 1, 1138)
model.set(iter, 2, 3.14)
This appends a new row and sets the values”foobar”,1138 and 3.14 to the three columns. You can avoid the three different calls by sending in a list to append as the first argument, eg:
model.append([“foobar”, 1138, 3.14])
Which again, is the exact same thing. (Modula saving a reference to the inserted tree iter of course)
Fetching values
To fetch a value from the a model you usually get an iter, for example from a selection:
model, path = selection.get_selected()
value = model.get_value(model.get_iter(path) , 0)
Two things can be simplified here: First of all we take advantage that model implementes a list like api, you can just access the model list a list, eg: model[n]. Secondly you can send in either an index, path or iter as n, so the example above is simplified to:
model, path = selection.get_selected()
value = model[path][0]
Iteration
Iteration over all the values in the model is usually done something like this:
iter = model.get_iter_first()
while True:
value = model.get_value(iter, 0)
iter = model.iter_next(iter)
if iter is None:
break
Which can also be considerably simplified:
for row in model:
value = row[0]
Also note that using the variable name iter in a python program is always wrong, since there is a builtin variable with the same name. Avoid the name iter, and use for instance titer instead, which is almost as short and a bit clearer.