GObject Properties

18 05 2008

After creating a number of signals and functions on my own to handle my class’ fields, I reaised that GLib 1-uped me, and already has a frame work for that; properties. Properties are well exposed to the rest of the framework, can be elegantly handled using the g_object_set and g_object_get functions, and of course, emit signals whenever they are modified. This means you get signal creation free of cost. This was something I didn’t find well treated in the tutorial.

There is a lot of boiler plate code that goes into enabling properties. An outline of the process (which is very well documented in the standard tutorial):

  1. #define a bunch of macros with a unique number for each property.
  2. Register the property in the _class_init using the g_param_spec_ () function and gobject_class_install_property (), with the aforementioned number.
  3. Implement functions for the _get_property and _set_property functions. This is done using a switch-case on the property_id, matched the macros. You can either code how to get/set the property inline in each case statement, or call functions for them (depending on the complexity).

If it all boils down to just calling get/set functions anyway, you may question the whole point of properties. Some reasons to make you think otherwise (following the same theme as previous posts):
1) A clean way of setting fields while constructing objects:

plot = g_object_new (PLOTS_TYPE_WDP,
"probabilty", 0.42, // probability of success
"codename", "Polka-dotted Panther", // Something jazzy
"schedule", NULL, // Who needs timelines anyways?
NULL);

2) A similar way of getting and setting properties:

g_object_set (obj,
"probabilty", 0.23, // Things are never as optimistic as you make them out to be
// the codename sounds cool enough
"schedule", &last_minute, // Procrastination != cool
NULL);
// _get puts the value of the fields into the variables
g_object_get (obj, // To put on the list of "yet another plan that failed"
"codename", &codename,
NULL);

3) Signal emission, via the “notify” signal:

// listen for whenever probability changes
sig_id = g_signal_connect (plot,
"notify:probability",
(GCallback)back_to_the_drawing_board, // The function checks if probability = 0
NULL);
// Note, the callback has a special argument, the properties' specification:
back_to_the_drawing_board (PlotsPlot *plot, GParamSpec *param, gpointer user_data);

In an enlightening discussion with the davyd on #gnome-hackers, he told me how you can use these notify signals to elegantly connect up widgets to their models, thus really creating a MVC (Model-View-Controller) framework. Certain properties expose other useful snippets data like min/max value for the G_PARAM_SPEC_INT property, which could be used on a spin-controller. Sadly, there is no ready-made function to link up a widget and a data ‘source’. I haven’t done it myself, so I can’t comment on how easy/hard it may be, but according to davyd it’s simple, and largely boilerplate.

4) Your objects are now introspectable (I honestly don’t understand the implications of this)
5) Your objects can be easily language-binded
6) You’ll be seeing lots of properties in all sorts of objects, for example GTK+ widgets. Might as well get used to it. People using your code will expect the same.

Advertisements

Actions

Information

4 responses

18 05 2008
A. Walton

“Sadly, there is no ready-made function to link up a widget and a data ’source’.”

There’s actually code out there that does this, and there’s a somewhat quiet group of us who’d like to see it moved into GLib, but it probably needs some more discussion with the GLib janitors. Anyways, the code’s in libexo from XFCE: http://www.xfce.org/documentation/api/exo/exo-Binding-Properties-Functions.html

By “binding” two properties together, you can quickly have the UI follow and adjust the data. I’ve extracted the code from the library and used it in gadgets I’ve worked on from time-to-time, and I’m extremely happy with it (it’s just so easy to do
_g_object_mutual_bind (canvas_item, “hscale”, control_adjustment, “value”);
and have a spin-button that controls the horizontal scale of an item. I’d highly recommend you look into it.)

If paired with something like Glade, property binding could become extremely popular (think: Interface Builder in Mac OS X, with drag-and-drop widget connecting). Then all it’d need is the ability to generate subclassed object stubs and we’d be off to taking over the world… 😉

Hope that helps,
-A.Walton

18 05 2008
arunchaganty

@ A. Walton: It sure does! I’ve never heard of libexo before, but it’s excellent! I hope it’s accepted into GLib. Perhaps it could be integrated into glade as well (at least for limited cases with just other widgets (like in the example provided), just like call handlers are now).

19 05 2008
Stefan Kost

There is a ticket for it
http://bugzilla.gnome.org/show_bug.cgi?id=348080

It would need someone to push it though.

Regarding 4) Introspectable:
It means one can query the members of a class ina generic way. One example: all gstreamer components a gobjects. My hobby project (http://www.buzztard.org) is a music composer. There you can use all available gstreamer effects and generators. Now you also want to configure them and I generate the gtk UI by introspecting the properties. I query a list of properties and then loop over them. if its a boolean, I create a checkbox, for enums a dropdown, for double/float a slider, for int a spinbutton, for strings a textentry, ….

29 05 2008
sudharsh

You should look at the vala way for using properties
http://live.gnome.org/Vala/PropertiesSample

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




%d bloggers like this: