On Sun 11/26, [EMAIL PROTECTED] < [EMAIL PROTECTED] > > I am about to start a new app, and would like to improve my > programming style. I have been using global variables to pass data > from "popup" windows back to a main window. I have seen discussion > about using g_object_set_data, but have not progressed to being > able to use it confidently.
g_object_set_data() simply stashes a pointer within the object, under the given name. That's pretty much all you need to remember. The only real gotcha, is that you have to be careful to free that pointer value if it points to allocated memory (hence the g_object_set_data_full() function, but that's another story). One of the places where I've found g_object_set_data() invaluable, is in extending the operation of a widget; for example, linking two numeric entry widgets as a min/max pair. You set the pointer for the min widget on the max widget, using g_object_set_data() (and an appropriately named slot), and vice-versa. You then attach a value changed handler to each object which checks for the "min" widget pointer, and makes pulls it down if necessary, and checks for the "max" widget pointer, and pulls it up if necessary. Then you wrap it up in a helper function which is passed two widgets, sets the data on each, and attaches the handler functions. You can use the helper function time and again anywhere where you need a min/max pair of numeric entries. (It'd probably work for a min/cur/max triplet too.) Another which I've found handy (though slightly more complex), was to attach to each widget using g_object_set_data(), a pointer to a variable in which the value should be stored (usually within an already-g_malloc()'d struct). There's a few examples of a recursive foreach-widgets type function floating around, which can then walk the dialog, calling another function on each one as it goes. This new function looks for widgets with the data item set, and either puts the value from the widget into the address specified, or plucks the value out of the variable and sticks it into the widget. (Of course, it needs a little magic to test what sort of widget it is, and use the correct functions.) The same principal can also be used for database connectivity, though there are generally better ways of achieving that, I'd expect. This sort of mechanism comes in magical for those "OK", "APPLY", "REVERT", "CANCEL" type situations. You have a master copy of the struct, then when you create your dialog you also allocate a copy of the struct. Then once the dialog is built, you call a function to fill in the variable check boxes, entries, buttons, and what-not. On an "OK" response, you copy everything back again. On a "CANCEL", you simply ignore it, and "APPLY" and "REVERT" simply call the two functions to move data back and forth as appropriate. As an added touch, you use g_object_set_data_full() to attach the malloc()'d copy of your master struct to the dialog widget itself, with the DestroyNotify function set to g_free(). This means that not only is the struct available if something needs it (or if, as I often do, you simply hide frequently-used dialogs instead of destroying them), but it'll get cleaned up along with the dialog itself. If you keep the dialog around, you keep the struct also, and just re-fill it from the main struct, call the function to fill the dialog widgets from it, and then call gtk_window_present() to re-show the dialog. Along the same vein, I've used g_object_set_data() to hold the original value of a widget, and attached a handler that set or cleared an indicator on the widget when the value was anything other than its original setting. (It makes a bit more sense when linked with the apply/revert mechanism.) These are the sorts of things I've personally used g_object_set_data() and friends for... The best part of doing it this way, is the linkage of the dialog widgets to the variables within the struct is done right there as you're building the dialog (of course, it's not quite so much use if you're using Glade... In that case, the usual mass-get/set function pair is probably cleaner). > Does anyone know of a simple example using g_object_set_data. The > sort of thing I am thinking about is a main window with a label > and button, that pops up a child window with an entry and a > button. Clicking the child windows button returns the string in > the entry back to the main windows label. In this case, the child window should probably be a dialog, and you'd attach to its response signal. When you get the "OK" response, you'd fetch the value from the entry and assign it to the label, or whatever you plan on doing. Not really much need for a g_object_set_data() there... Fredderic _______________________________________________ Join Excite! - http://www.excite.com The most personalized portal on the Web! _______________________________________________ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list