Re: Pass 2 or more widgets in callback



What is the "correct" way to pass more than one widget in the data param
of a callback? I tried passing an array of GtkWidget* and a g_list, but
it didn't work. The approach that worked was to get one of the widget
and set pointers to the others with gtk_object_set_data, and then
gtk_object_get_data inside de callback. I wonder if there is a better
way to do it.

You can pass ANY address as a gpointer data, 
in particular you can pass an array (gpointer 
is basically a pointer to void).

the best option really depends of your data:

- you can pass the array directly (with all elements inside);

- you can pass a struct containing the array;

- you can pass a struct containing each element of the array;

- you can pass ONE get_data/set_data
pointing to the array;

- you can pass one get_data/set_data for
EACH element of array

If you are trying to pass the addresses of a constant number of
widgets used in a dialog to a callback, known at compile time,
then I can give you my opinion, feel free to ignore it: ;-)

- forget about arrays to pass widgets; you would have to
remember that the 37th position is entry C and 38th is
radio button A, a nightmare, if you change the widget
in the 1st position you are likely to change the whole array.
You could use enumerations but then you would be using precious
name space, you would end up with lots of enums all around...

- forget about structtures to pass the whole bunch of widgets;
if you have 50 different dialogs in your app, you will end up
with 50 different structs, which sole purpose is pass data
around, spread all over the code. You could define them in
a single place, but then you would have to define 50 typedefs
basically for nothing, again using precious name space, etc...

- use the precious data parameter to pass a structure that
contains YOUR permanent data, that contains all the information 
you need in callbacks and possibly everywhere. This structure
ideally will be the same for ALL your dialogs and callbacks.
Inside this structure, create a pointer to store the address 
of each class of dialog that you have (often just one, but for 
example help dialogs, input dialogs, message dialogs, etc. might 
belong to different classes, some might be modal, some not, etc.).

- Use set_data/get_data to attach all the widget information
you need to the dialog widget. Use a sistematic notation all
over your app to choose the string description in get_data/set_data.
Then put the dialog address in the pointer address in the struct. This way:

i) from the data parameter you have access to all your PERMANENT data,
which is inside the structure;

ii) from the data parameter you have access to the dialog widget address,
which in turn is attached to all the widget addresses, so you have
access to all the TEMPORARY widget data as well.

iii) everytime you want to add or remove a new widget which address
you need, you just need to add or remove a new set_data/get_data.
This data is totally independent of the other set_data/get_data.

iv) when you destroy the dialog widget, gtk+ will destroy automatically
all widgets inside AND all g_lib allocations done with get_data/set_data,
so you really don't need to worry about freeing memory. The ONLY thing
you need to do is destroy the dialog (and change the dialog pointer in 
your struct to NULL) and everything else is done automatically for you.

v) get_data/set_data is slower than creating an array with widget
addresses, sure. If you have thousands of widgets in your dialog
(or if you don't know its exact number at compile time), then 
get_data/set_data is not for you. But if (as in 99% of the cases)
 you have 20, 50, 100 widgets whose addresses you need to know, then 
get_data/set_data is simpler and speed (or memory) is NOT a problem 
at all.

Carlos




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