Re: what's the best way to handle variables and objects?
John (J5) Palmieri wrote: Yes. It depends on your application. Some people will subclass a GObject and add the window object plus all of the other widgets as aggregates. If you are feeling more daring you can subclass your main window where your app class would inherit from GtkWindow. However if you do not want to get into the intricacies of GObject inheritance simply creating a struct would be fine: I agree. Usually it don't make sense to create a whole GObject descendant just to pass some data. On the other hand it really make sense if we want to use OOP/GObject mechanisms like subclassing, (virtual) methods and reference counting. It depends on the complexity of the application. Cheers, Andy ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
what's the best way to handle variables and objects?
I'm looking for a clean solution on passing variables and objects from gtk calls to callback functions and back. I call for instance g_signal_connect(G_OBJECT(button), clicked, G_CALLBACK(clear_timer_cb), progressbar); and pass with it the object I'm working with. (progressbar has been definded before: GtkWidget *progressbar = gtk_progress_bar_new(); ) now in clear_timer_cb I can modify the object: void clear_timer_cb(GtkObject *window, void *data) { GtkWidget *progressbar = data; gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progressbar), 0); } but what should I do if I want to modify any other variables in this function as well? let's say that in the part where I created the g_signal_connect there are also some variables A and B which might be of interest in clear_timer_cb. should I create a struct struct data { gdouble *A; gdouble *B; GtkWidget *progressbar }; and then initiate it and pass it always on? what's the best way in dealing with this? cheers, Andreas ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: what's the best way to handle variables and objects?
Andreas Kotowicz wrote: [...] but what should I do if I want to modify any other variables in this function as well? let's say that in the part where I created the g_signal_connect there are also some variables A and B which might be of interest in clear_timer_cb. should I create a struct struct data { gdouble *A; gdouble *B; GtkWidget *progressbar }; and then initiate it and pass it always on? what's the best way in dealing with this? This is a typical, popular and clean way to pass mulitple variables/addresses to a callback, yes. If you allocate a struct for that a g_signal_connect time... you might want to consider useing something like g_object_weak_ref() to free your struct when the button you connected to is finalized (maybe there is a g_signal_connect_data_full variation that does this for you ?). Cheers, -Tristan ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: what's the best way to handle variables and objects?
On Wed, 2006-03-15 at 13:44 -0500, John (J5) Palmieri wrote: You can create a generic struct but more often than not there is an application object or struct that the application developer creates which holds all the public variables he or she would care about which is passed as userdata to things like g_signal_connect. sorry, but I don't exactly understand what you mean. Could you maybe give me an example of how the application object and the interaction would look like? would this application object also hold all the labels and entry fields which might change? but maybe I do understand you. what I use here is following: main.c: #include gtk/gtk.h #include interface.h int main (int argc, char *argv[]) { GtkWidget *window1; gtk_init(argc, argv); window1 = create_window1 (); gtk_widget_show_all(window1); gtk_main(); return 0; } interface.h: #include gtk/gtk.h GtkWidget* create_window1 (void); interface.c: #include callbacks.h #include interface.h GtkWidget* create_window1 (void) { GtkWidget *window; GtkWidget *vbox; GtkWidget *progressbar; GtkWidget *button_start; GtkWidget *spin_sec; GtkWidget *spin_min; window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), Window); g_signal_connect(G_OBJECT(window), destroy, G_CALLBACK(destroy_window_cb), NULL); /* vbox for whole window */ vbox = gtk_vbox_new(FALSE, 6); gtk_container_add(GTK_CONTAINER(window), vbox); /* put progressbar at the top of the window */ progressbar = gtk_progress_bar_new(); gtk_box_pack_start(GTK_BOX(vbox), progressbar, TRUE, TRUE, 12); /* entry field for number of seconds */ spin_sec = gtk_spin_button_new_with_range(0, 59, 1); gtk_box_pack_start(GTK_BOX(vbox), spin_sec, FALSE, FALSE, 0); button_start = gtk_button_new_with_mnemonic(_Start); gtk_box_pack_start(GTK_BOX(vbox), button_start, FALSE, FALSE, 0); g_signal_connect(GTK_BUTTON(button_start), clicked, G_CALLBACK(start_timer_cb), progressbar); return window; } is this what you mean by application object? here comes my problem now: g_signal_connect on button_start only passes on the progressbar object to start_timer_cb(). but I also want to have the user input from spin_sec in this function. so how can I get a grip on both of these (or even more) variables in start_timer_cb() ? callbacks.c: void start_timer_cb(GtkObject *window, void *data) { GtkWidget *progressbar = data; gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progressbar), gtk_progress_bar_get_fraction(GTK_PROGRESS_BAR(progressbar))+0.1); } BTW GtkObject is usually not used directly anymore. Usually objects are passed to callbacks as GObject, GtkWidget or their actual class (in your case GtkButton) as they are the most useful casts. thanks, good to know. andreas ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: what's the best way to handle variables and objects?
My reply's in the body (I ain't no top-poster!): On Wed, 2006-03-15 at 22:57 +0100, Andreas Kotowicz wrote: On Wed, 2006-03-15 at 13:44 -0500, John (J5) Palmieri wrote: You can create a generic struct but more often than not there is an application object or struct that the application developer creates which holds all the public variables he or she would care about which is passed as userdata to things like g_signal_connect. sorry, but I don't exactly understand what you mean. Could you maybe give me an example of how the application object and the interaction would look like? would this application object also hold all the labels and entry fields which might change? but maybe I do understand you. what I use here is following: main.c: #include gtk/gtk.h #include interface.h int main (int argc, char *argv[]) { GtkWidget *window1; gtk_init(argc, argv); window1 = create_window1 (); gtk_widget_show_all(window1); gtk_main(); return 0; } interface.h: #include gtk/gtk.h GtkWidget* create_window1 (void); interface.c: #include callbacks.h #include interface.h GtkWidget* create_window1 (void) { GtkWidget *window; GtkWidget *vbox; GtkWidget *progressbar; GtkWidget *button_start; GtkWidget *spin_sec; GtkWidget *spin_min; window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), Window); g_signal_connect(G_OBJECT(window), destroy, G_CALLBACK(destroy_window_cb), NULL); /* vbox for whole window */ vbox = gtk_vbox_new(FALSE, 6); gtk_container_add(GTK_CONTAINER(window), vbox); /* put progressbar at the top of the window */ progressbar = gtk_progress_bar_new(); gtk_box_pack_start(GTK_BOX(vbox), progressbar, TRUE, TRUE, 12); /* entry field for number of seconds */ spin_sec = gtk_spin_button_new_with_range(0, 59, 1); gtk_box_pack_start(GTK_BOX(vbox), spin_sec, FALSE, FALSE, 0); button_start = gtk_button_new_with_mnemonic(_Start); gtk_box_pack_start(GTK_BOX(vbox), button_start, FALSE, FALSE, 0); g_signal_connect(GTK_BUTTON(button_start), clicked, G_CALLBACK(start_timer_cb), progressbar); return window; } is this what you mean by application object? here comes my problem now: g_signal_connect on button_start only passes on the progressbar object to start_timer_cb(). but I also want to have the user input from spin_sec in this function. so how can I get a grip on both of these (or even more) variables in start_timer_cb() ? Define a struct that has as it's member fields all the values you want accessible to the callback, including the progressbar, spin_sec, etc: struct MyUserData { GtkWidget *progress_bar; GtkWidget *spin_sec; }; Allocate one of these on the heap (note: I'm using C++, so new's what I use for this): MyUserData *myData = new MyUserData; myData-progress_bar = progressbar; myData-spin_sec = spin_sec; Pass the allocated storage as the last parm to g_signal_connect. g_signal_connect(GTK_BUTTON(button_start), clicked, G_CALLBACK (start_timer_cb), myData); In the callback, cast the pointer to the user-supplied parm to the type of your struct and access it's members as needed: void start_timer_cb(GtkObject *window, void *data) { MyUserData *myData = (MyUserData*)data; // the progressbar is myData-progress_bar, etc. // ... } Remember to return the storage to the heap when you're done using it. // Wally -- Your eyes are weary from staring at the CRT. You feel sleepy. Notice how restful it is to watch the cursor blink. Close your eyes. The opinions stated above are yours. You cannot imagine why you ever felt otherwise. ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: what's the best way to handle variables and objects?
On Wed, 2006-03-15 at 22:57 +0100, Andreas Kotowicz wrote: On Wed, 2006-03-15 at 13:44 -0500, John (J5) Palmieri wrote: You can create a generic struct but more often than not there is an application object or struct that the application developer creates which holds all the public variables he or she would care about which is passed as userdata to things like g_signal_connect. sorry, but I don't exactly understand what you mean. Could you maybe give me an example of how the application object and the interaction would look like? would this application object also hold all the labels and entry fields which might change? Yes. It depends on your application. Some people will subclass a GObject and add the window object plus all of the other widgets as aggregates. If you are feeling more daring you can subclass your main window where your app class would inherit from GtkWindow. However if you do not want to get into the intricacies of GObject inheritance simply creating a struct would be fine: typedef struct _FooApp { gchar *app_name; GtkWidget *main_window; GtkWidget *progress_bar; GtkWidget *button_start; } FooApp; FooApp * create_app (void) { FooApp *app; app = g_new0 (FooApp, 1); app_name = g_strdup (My Foo App); app-main_window = ... app-progress_bar = ... gtk_container_add (GTK_CONTAINER (app-main_window), app-progress_bar); . . . g_signal_connect(app-button_start, clicked, G_CALLBACK(start_timer_cb), app); gtk_widget_show_all (app-main_window); return app; } but maybe I do understand you. what I use here is following: main.c: #include gtk/gtk.h #include interface.h int main (int argc, char *argv[]) { GtkWidget *window1; gtk_init(argc, argv); window1 = create_window1 (); gtk_widget_show_all(window1); gtk_main(); return 0; } interface.h: #include gtk/gtk.h GtkWidget* create_window1 (void); interface.c: #include callbacks.h #include interface.h GtkWidget* create_window1 (void) { GtkWidget *window; GtkWidget *vbox; GtkWidget *progressbar; GtkWidget *button_start; GtkWidget *spin_sec; GtkWidget *spin_min; window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), Window); g_signal_connect(G_OBJECT(window), destroy, G_CALLBACK(destroy_window_cb), NULL); /* vbox for whole window */ vbox = gtk_vbox_new(FALSE, 6); gtk_container_add(GTK_CONTAINER(window), vbox); /* put progressbar at the top of the window */ progressbar = gtk_progress_bar_new(); gtk_box_pack_start(GTK_BOX(vbox), progressbar, TRUE, TRUE, 12); /* entry field for number of seconds */ spin_sec = gtk_spin_button_new_with_range(0, 59, 1); gtk_box_pack_start(GTK_BOX(vbox), spin_sec, FALSE, FALSE, 0); button_start = gtk_button_new_with_mnemonic(_Start); gtk_box_pack_start(GTK_BOX(vbox), button_start, FALSE, FALSE, 0); g_signal_connect(GTK_BUTTON(button_start), clicked, G_CALLBACK(start_timer_cb), progressbar); return window; } is this what you mean by application object? here comes my problem now: g_signal_connect on button_start only passes on the progressbar object to start_timer_cb(). but I also want to have the user input from spin_sec in this function. so how can I get a grip on both of these (or even more) variables in start_timer_cb() ? callbacks.c: void start_timer_cb(GtkObject *window, void *data) { GtkWidget *progressbar = data; gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progressbar), gtk_progress_bar_get_fraction(GTK_PROGRESS_BAR(progressbar))+0.1); } BTW GtkObject is usually not used directly anymore. Usually objects are passed to callbacks as GObject, GtkWidget or their actual class (in your case GtkButton) as they are the most useful casts. thanks, good to know. andreas -- John (J5) Palmieri [EMAIL PROTECTED] ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: what's the best way to handle variables and objects?
Andreas Kotowicz wrote: Hi Tristan, [...] do you know maybe a relatively simple gnome app which uses this concept, so I could have a look at the source code and see how all the interaction works? Well, how about I just type away from memory... after writing that I notice that its probably not something one would do... but it should give you some good ideas ;-) Cheers, -Tristan typedef struct { GtkWidget *prog; gint a; gchar *str; } MyStruct; /* . . . */ static void my_destroy (MyStruct *my) { if (my-str) g_free (my-str); g_free (my); } /* . . . */ MyStruct * my = g_new0 (MyStruct, 1); http://developer.gnome.org/doc/API/2.0/glib/glib-Datasets.html#GDestroyNotifyg_signal_connect_data (G_OBJECT(adj), value-changed, G_CALLBACK (progress_callback), my, (GDestroyNotify)my_destroy, 0); /* . . . */ static void progress_callback (GtkWidget *button, MyStruct *my) { /* do something rediculous like set the progress bar percentage * to match the adjustment. */ } ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list