RE: Passing data from a data collection window back to a main




On Sun 11/26, ksadil bigpond net au < ksadil bigpond net au >
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!





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]