Attaching Data to Objects

You can "attach" arbitrary string-pointer pairs to a GtkObject instance, in effect adding a new data member. GTK+ uses this some internally, but it can also be a convenient way to pass data around in your application. In particular, it's a nice way to pass information to callbacks.

Here's a simple example:


    GtkWidget* button = gtk_button_new();
    GtkWidget* label  = gtk_label_new(_("Foo"));
  
    gtk_object_set_data(GTK_OBJECT(button), "my_label_key", label); 
  

Later, when you have a pointer to the button but not the label (perhaps in a callback connected to the button's "clicked" signal), you can do this:


    GtkWidget* label = gtk_object_get_data(GTK_OBJECT(button),
                                           "my_label_key");

    /* If no data is found for the key, NULL is returned. */

    if (label == NULL)
      {
        g_warning("No data was associated with 'my_label_key'!");
      }
  

A pair of convenience functions use a predetermined key and thus save typing (and remembering) the object data key. These are gtk_object_set_user_data() and gtk_object_get_user_data(). You can also register a function to free the data when the data is removed or replaced, or the GtkObject is destroyed; This function should be of type GtkDestroyNotify:


  typedef void (*GtkDestroyNotify) (gpointer data);

Conveniently, g_free() and gtk_object_unref() will work here. You register a "destroy notification" function when you set the data, using gtk_object_set_data_full(). You can remove data before the object is destroyed with gtk_object_remove_data(), or remove it without calling the destroy function with gtk_object_remove_no_notify(). Setting the data to NULL is equivalent to removing it with gtk_object_remove_data(), and will also call the destroy function if you registered one. Figure 6 summarizes the object data functions.

It's worth pointing out that the object data system is a thin wrapper around the GData facility in glib, which can be used standalone.

#include <gtk/gtkobject.h>

void gtk_object_set_data(GtkObject* object, const gchar* key, gpointer data);

void gtk_object_set_data_full(GtkObject* object, const gchar* key, gpointer data, GtkDestroyNotify destroy);

void gtk_object_remove_data(GtkObject* object, const gchar* key);

gpointer gtk_object_get_data(GtkObject* object, const gchar* key);

void gtk_object_remove_no_notify(GtkObject* object, const gchar* key);

void gtk_object_set_user_data(GtkObject* object, gpointer data);

gpointer gtk_object_get_user_data(GtkObject* object);

Figure 6. Attaching key-value pairs to a GtkObject