Simplified GObject properties

Today I spent most of the day to finish off an implementation of bug 338098, adding a property helper to the python gobject bindings.

The support for defining your own GObject properties in PyGObject/PyGTK has always been a nail in my eye:

  • You need to create a dictionary filled with crazy options
  • You need to implement get_property and set_property to store/retrieve the values for each property.
  • There’s very little help if you do a mistake, a cryptic error message will be displayed which gives you insufficient clues to figure out what you’ve done wrong.

A long time ago I solved this in kiwi. But I never quite got around to submit these helpers to pygobject where they belong.

With the new property helper it gets much simpler. Let’s say you want to create a new object called Color which has the three integer properties called red, green and blue:

  class Color(gobject.GObject):
    red = gobject.property(type=int)
    green = gobject.property(type=int)
    blue = gobject.property(type=int)

That’s it!
Easy to read and understand.

If you want to set a property, just modify the properties as if they were a normal python attribute:

  color = Color()
  color.red = 10
  color.green = 20
  color.blue = 300

Same goes for access:

  >>> color.green
  20

Now, suppose you want a read-only property, then you can use the “new” python 2.4 decorator syntax:

  @gobject.property
  def fnorb(self):
     return 'fnuffra'

Which will add a fnorb property which will always return the string ‘fnuffra’ and raise an exception if your try to modify it.

The patch has not yet landed in pygobject’s SVN repository, but it’ll probably go in shortly, assuming nobody have any objections.

Once this is done I intend to work on a similar solution for signals.

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

4 Responses to Simplified GObject properties

  1. Ali says:

    Nice work Johan! What about the case where we want accessors/mutators?

  2. Johan says:

    Ali: If you want to define your own accessors you can do that in a way similar to the builtin property():

    class Object(gobject.GObject):
    def get_prop(self):
    return self._value

    def set_prop(self, value):
    self._value = value
    prop = gobject.property(get_prop, set_prop)

    But then you obviously have to take care of the storage of the value yourself.

  3. Nice, now you just need to do the same for signals! Kiwi has a much easier way to define them.

  4. Alberto Ruiz says:

    Nice work Johan!

    This is the kind of features every binding should has, take advantage of the language.

Comments are closed.