May 6, 2008
GNOME, General, PyGTK, Python, olpc
19 Comments
I have the pleasure of knowing the great mpt. He actually spent a couple of months in Brazil back in 2006 and we ended up sharing the same apartment during this period. One of the great things he masters is the art of writing ascii art mockups of user interfaces As I am a mere beginner might not be the best person to explain this. However I will make an attempt to explain the basic principles, in the effort of having this written down somewhere.
In this blog post I will focus on commonly used interactive widgets available in Gtk+, since these are the ones I tend to care the most about.
GtkEntry
An entry is straight forward, you use brackets in the beginning and the end and underscores to fill up the allocated width of the widget:
[____________]
If you want a text, just replace the underscores with letters
[Hello World____]
GtkButton
Buttons are similar to entries, the main difference is the lack of underscores and the use of capital letters. Icons are usually ignored as they often are rather tricky to represent using the ASCII alphabet. A cancel button looks like this:
[ CANCEL ]
GtkToggleButton and GtkRadioButton
Toggle buttons uses brackets around the toggle part and no brackets around the rest. If the value of the radio should be active, use a lowercase x to say so:
[ ] Buy milk and cheese for breakfast
[x] Eat strawberries after lunch
Radio buttons are similar but uses parenthesis and o, eg:
(o) Fresh fish
( ) Rotten eggs
GtkSpinButton
Spin buttons are similar to entries, but they have two small arrows on the right hand side. To represent the arrows, use H:
[1234 H]
This might not look good in all fonts, but it’s the best that can be done, at least as far as I know.
GtkComboBox
A combobox tend to be represented again by using brackes in the beginning and the end. To represent the arrow, use a lower case v and separate it from the text by using a | (pipe) sign.
[ Stockholm | v]
GtkDialog
Prett simple, use _ (underscore) and | (pipe) for the borders, titles and window manager buttons can usually be skipped since they are mostly noise to us in this context:
________________________________
| |
| Do you want to close the open |
| document and lose the changes |
| made to it? |
| [ CONTINUE ] [ QUIT ] |
|________________________________|
These are the widgets I usually end up using in my mockups. Have any missed any important onces? Or I have I done any serious mistakes? Comments appreciated!
Read the rest…
May 6, 2008
GNOME, General, PyGTK, Python
4 Comments
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.
May 5, 2008
General
1 Comment
Last week was not a very good one, at least not accident wise.
On Monday evening (a week ago today) I went to the bakery to get some bread and juice. Our poor dog hadn’t been out for a walk for a day or two so I decided to take her with me. Olivia is a 5 years old boxer who has been with us at the company for a long while, she’s very obedient and she’s free to run on the sidewalks without using a leash. She was very happy to go and ran off quickly, sticking to the sidewalk without entering the street. I walked by and let her run by herself. As we approached the first crossing she forgot, in a moment of joy to look at me if it was okay to pass the street and she ran over. Usually this kind of mistakes just end up with me telling her off. This was not her lucky day, a car approached and ran right into her. Luckily the car was not running very fast and the driver quickly hit the breaks. Olivia was not actually ran over, but she got up on her two legs and ran back towards the office without giving a sound. At this point I did not know if she was injured or not, so I started to run after her. A moment later, when I came back the office she wasn’t there. I spent the next two hours on my bike driving around the city trying to find her. Eventually through a couple of leads by pedestrians I could locate her in a corner about a km from where the accident had occurred. She was quickly brought to the vet would could only establish that she was well and had nothing broken. She had a couple of her pads on her front feet torn off, probably due to the shock and had a bit of pain walking. Today a week later she’s just fine, like nothing happened.
My second traffic incident of the week occurred when I came back after a 60km bike ride on Saturday evening. My Saturdays afternoons/evenings are reserved for bike riding and last week wasn’t an exception. We tend to leave around 14 and are seldom back before the sunset. When we came back on saturday it was not completely pitch dark, but it wasn’t many minutes of brightness left. As out of no where, a white VW Beetle overturns me, giving me approximately 2 m for me to either break or turn. Obviously I ran into the car with my front wheel, lost balance and smashed the asfalt pretty badly. My helmet cracked and the jersey got thorned apart, no serious injuries, just abrasions. What upset me the most was the fact that while the driver stopped to check if I was okay, he refused to acknowledge any wrong doing, merely telling me that “I couldn’t see you”. I will take it a lot easier in the future, especially when riding in darkness and cities. Moral of the story, as a cyclist, do not ever trust other drivers when riding in urban areas.