how to get selection from a gtk3 combobox with tree model - combobox

I'm new to GTK. The last GUI application I wrote used the text mode GUI in Turbo C, so I have a little catching up to do.
I'm using GTK to write a test harness for some code that will eventually be in an embedded system. I'm using a combobox with a tree model to provide a 2-level selection. I got the combobox to display as I wanted, although I don't have a good understaning of the cell_renderer parts that I just copied and pasted from another stack overflow question.
GtkTreeStore* model = gtk_tree_store_new(1,G_TYPE_STRING)
(Initilise model to hold desired strings using
gtk_tree_store_append and gtk_tree_store_set)
GtkWidget* combobox = gtk_combo_box_new_with_model(model);
gtk_combo_box_set_entry_text_column(combobox, 0);
GtkCellRenderer *column = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combobox),column,TRUE);
gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combobox), column,"text", 0,NULL);
This code worked to display the combobox. Now I needed to get the selection from the combobox. I tried getting an index from the combobox using gtk_combo_box_get_active (). The index returned didn't help me. For sub-tree items, It only showed the position relative to the parent. So, I tried to pull out the text of the selected option. A bit more searching found me this line to pull the text from the combobox:
gchar * selection = gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(MyCombobox))));
however, calling this gave me the following error, and returned (null).
(test.exe:3040): GLib-GObject-WARNING **: invalid cast from `GtkCellView' to `GtkEntry'
(test.exe:3040): Gtk-CRITICAL **: gtk_entry_get_text: assertion `GTK_IS_ENTRY (entry)' failed
So, a bit more googling indicated that I need to initialise the combobox with an "entry", so updated my initialisation of the combobox to:
combobox = gtk_combo_box_new_with_model_and_entry(model);
And partial success!!. Now I can pull the text from the combobox, but it displays the selection text twice, on the combobox drop-down. Once the selection is made, it displays single in the box itself. so, if my model text is:
opt10
opt11
opt20
opt21
The tree displays each item twice (selecting first opt11)
[opt10 opt10] > opt10 opt10
[opt11 opt11]
opt20 opt20 >
Once I make my selection, (say opt11) the combobox shows the selected text correctly, and my call to gtk_entry_get_text(.....) returns the text "opt11" like I expect.
So, I'm at a dead-end. I want to query the combobox to get either an index that uniquely identifies the item in the tree, or a text string. I have the text string method working, but it makes the combobox options display twice.
Help?
Thanks,

This should work... Compile this code with the command in the comments. This is the 'full' version, using a model and such... If you just want to select a name from a list, you can use GtkComboBoxText, which is easier to use...
/*
* main.c
* Copyright (C) 2015 John Coppens <john#jcoppens.com>
*
* standalone_filechooser is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* standalone_filechooser is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*
* gcc -o main `pkg-config --libs --cflags gtk+-3.0` main.c
*/
#include <stdio.h>
#include <gtk/gtk.h>
int
on_destroy(GtkWidget *win, gpointer data)
{
gtk_main_quit();
return FALSE;
}
void
sel_changed(GtkComboBox *cbbox, gpointer data)
{
GtkListStore *store;
GtkTreeIter iter;
int item_nr, ok;
char *item;
ok = gtk_combo_box_get_active_iter(cbbox, &iter);
printf("%i\n", ok);
store = GTK_LIST_STORE(gtk_combo_box_get_model(cbbox));
gtk_tree_model_get(GTK_TREE_MODEL(store), &iter,
0, &item_nr,
1, &item,
-1);
printf("Item: %s, nr: %d\n", item, item_nr);
g_free(item);
}
int main(int argc, char *argv[])
{
GtkWidget *win, *cbbox;
GtkCellRenderer *col;
GtkListStore *store;
GtkTreeIter iter;
int i;
char *items[] = {"Thingie 1", "Thingie 2", "Thingie 3"};
gtk_init(&argc, &argv);
win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(G_OBJECT(win), "destroy", G_CALLBACK(on_destroy), NULL);
store = gtk_list_store_new(2, G_TYPE_INT, G_TYPE_STRING);
for (i = 0; i < sizeof(items)/sizeof(char *); i++) {
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
0, i,
1, items[i],
-1);
}
cbbox = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
g_object_unref(store);
col = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(cbbox), col, TRUE);
gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(cbbox), col,
"text", 1,
NULL);
gtk_combo_box_set_id_column(GTK_COMBO_BOX(cbbox), 1);
g_signal_connect(G_OBJECT(cbbox), "changed", G_CALLBACK(sel_changed), NULL);
gtk_container_add(GTK_CONTAINER(win), cbbox);
gtk_widget_show_all(win);
gtk_main();
return 0;
}

Related

How to use images in GTK Stack Switcher using C

I'm making application in gtk using C. I have a GtkStack with GtkStackSwitcher and I don't know how to set images/icons to buttons in stack switcher. I had similar problem with application in gtkmm and C++ but I was able to find required function in the documentation. This time, after searching the documentation for GtkStack, GtkStackSwitcher and GtkContainer, I didn't find anything useful in GtkStack and GtkStackSwitcher. In GtkContainer there is function gtk_container_child_set_property (). It may be the function I'm looking for but I have no idea how to put an icon-name into GValue and if it's possible.
To sum up - can I set icon to GtkStackSwitcher's button with mentioned functions or using any other method?
Edit:
Maybe it's possible to achieve this with css? Setting background-image for GtkStack and GtkStackSwticher doesn't work but setting background_image for buttons works. Works very bad but works. The image doesn't fit the button and button doesn't resize to be the image size (If i set button new from pixbuf the button does resize). So is it possible with css or is it a dead end?
From the GtkStack documentation, at Child Properties, you can see the property "icon-name":
The “icon-name” child property
“icon-name” gchar *
The icon name of the child page.
Flags: Read / Write
Default value: NULL
As you pointed out, we can use gtk_container_child_set_property on the GtkStack (a GtkContainer) and set the icon. The problem is that the stack uses the icon or the title, not both.
Here is a simple example in C code:
#include <gtk/gtk.h>
int main (int argc, char** argv) {
GtkBox *box;
GtkStack *stack;
GtkLabel *label1;
GtkLabel *label2;
GtkWindow *window;
GtkStackSwitcher *switcher;
GValue iconval1 = G_VALUE_INIT;
GValue iconval2 = G_VALUE_INIT;
gtk_init (&argc, &argv);
g_value_init (&iconval1, G_TYPE_STRING);
g_value_init (&iconval2, G_TYPE_STRING);
window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
box = GTK_BOX(gtk_box_new(GTK_ORIENTATION_VERTICAL, 6));
stack = GTK_STACK(gtk_stack_new ());
switcher = GTK_STACK_SWITCHER(gtk_stack_switcher_new ());
label1 = GTK_LABEL(gtk_label_new("Stack Page 1"));
label2 = GTK_LABEL(gtk_label_new("Stack Page 2"));
gtk_stack_add_titled(stack, GTK_WIDGET(label1), "Page 1", "Page 1");
gtk_stack_add_titled(stack, GTK_WIDGET(label2), "Page 2", "Page 2");
gtk_widget_set_halign (GTK_WIDGET(switcher), GTK_ALIGN_CENTER);
g_value_set_string(&iconval1, "zoom-in-symbolic.symbolic");
g_value_set_string(&iconval2, "zoom-out-symbolic.symbolic");
gtk_container_child_set_property(GTK_CONTAINER(stack), GTK_WIDGET(label1), "icon-name", &iconval1);
gtk_container_child_set_property(GTK_CONTAINER(stack), GTK_WIDGET(label2), "icon-name", &iconval2);
gtk_stack_switcher_set_stack (switcher, stack);
gtk_box_pack_start (box, GTK_WIDGET(switcher), FALSE, FALSE, 6);
gtk_box_pack_start (box, GTK_WIDGET(stack), TRUE, TRUE, 6);
gtk_container_add (GTK_CONTAINER(window), GTK_WIDGET(box));
g_signal_connect(G_OBJECT(window), "destroy", gtk_main_quit, NULL);
gtk_widget_show_all (GTK_WIDGET(window));
gtk_main ();
return 0;
}
Compile it with:
gcc -o test main.c `pkg-config --cflags --libs gtk+-3.0`
and the result should be:
EDIT:
As requested in the comments:
Can you tell me also how to change icon sizes of stack switcher icons?
I see that stack switcher has property "icon-size"...
GtkStackSwitcher has the property "icon-size" but it was introduced in Gtk+ 3.20. So, in order to use this property there is this requirement.
To set a property to which Gtk+ does not provide a setter/getter you should use g_object_set (or set_full).
Using the code above:
...
switcher = GTK_STACK_SWITCHER(gtk_stack_switcher_new ());
g_object_set(G_OBJECT(switcher), "icon-size", GTK_ICON_SIZE_LARGE_TOOLBAR, NULL);
label1 = GTK_LABEL(gtk_label_new("Stack Page 1"));
...
The property is a gint value so you can try out some values and verify the size. There is also a enumerated type containing default sizes for icons, it's GtkIconSize. In the example i've used GTK_ICON_SIZE_LARGE_TOOLBAR (24px).

GtkCellRendererPixbuf and signals

Could anyone please give me a hint on how to attach a "double clicked" signal
to the pixbuf that is in the GtkTreeView? GtkCellRendererPixbuf
doesn't have any signals?
I managed to set the GTK_CELL_RENDERER_MODE_ACTIVATABLE switch to the
renderer, but I don't know how to work.
I checked the header file and in fact there is the "activate" method; could you please
demonstrate how to use it?
renderer = gtk_cell_renderer_pixbuf_new();
g_object_set(renderer, "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL);
column = gtk_tree_view_column_new_with_attributes(NULL,
renderer,
"pixbuf",
0,
NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
OK I try this:
Tree view's 'row-activated' will send the path and column as arguments
to the callback. With 'cursor-changed' just need to call
gtk_gtk_treeview_get_cursor to find out the path and column. With
gtk Widget's 'button-press-event' I get the event as an argument for
the callback and just need to call gtk_treeview_get_path_at_pos with
event x and event y to get the path and column.
A cell renderer is only supposed to draw the contents of the data model over a portion of the widget. Interaction with the user is in most cases realized using the widget itself.
In other words, simply connect to the button-press-event of the tree view and handle the case when the type is GDK_2BUTTON_PRESS. You can get the row/column under the mouse using gtk_tree_view_get_path_at_pos, as you do in your other question.
Check this:
void on_treeview_row_activated(GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *col, gpointer data)
{
GtkTreeModel *model;
GtkTreeIter iter;
model = gtk_tree_view_get_model( treeview );
if ( gtk_tree_model_get_iter(model, &iter, path) )
{
gtk_tree_model_get(model, &iter,
ITEM, &dhd_contaItem2,
CODIGO, &dhd_G_CodProduto2 ,
DESCRICAO, &dhd_G_NomeProduto2 ,
QTD, &dhd_quantidade2,
VALOR, &dhd_valorItem2,
-1);
g_print( "Current row: %s %s %s %s %s\n", dhd_contaItem2, dhd_G_CodProduto2, dhd_G_NomeProduto2, dhd_quantidade2, dhd_valorItem2 );
}
}
I use that in one of my codes to print in terminal the selected row from a TreeView (with ListStore) when double clicked or when you press enter on it. On the gtk_tree_model_get notice that I'm using my own columns and variables, as i do in g_print. And I attach this function with row-activated signal on the TreeView. I don't know if is that what you want exactly but I hope it helps you out. Sorry for my bad english.

GTK Linux C Get Input from Entry Box via Button Widget

I have a table that is filled with entry boxes, labels, and buttons.
Currently, if I compile the code, I can get input from a text box but only if the users presses the enter key, and the text only comes from the box they are currently typing in.
I would like to be able to get input from both text boxes when the "Login" button is pushed. I've tried using the same callback function that's used for enter key on the entry box, but GTK gives me an error.
If anyone could show me some code that would allow for me to get text from my entry boxes that are within tables (I know the method for retrieving data from tables and v/boxes is different) it would be greatly appreciated, as I can't seem to find it in any tutorials.
Will update w/working code.
Error when trying to attach status bar to table:
(Entry:5526): Gtk-CRITICAL **: gtk_table_attach: assertion `child->parent == NULL' failed
(Entry:5526): GLib-GObject-WARNING **: invalid cast from GtkTable' toGtkStatusbar'
Your callback function (named callback) needs to access both GtkEntry widgets in order to obtain their values. There are several ways this can be accomplished. Many GTK C programs use global variables, or global variables with file scope (ie a variable declared as static outside of any function within a file).
Remove your entry1 and entry2 variables near the top of the file before any functions:
static GtkWidget *entry1 = 0;
static GtkWidget *entry2 = 0;
And then modify the callback like so:
/* Our callback.
* The data passed to this function is printed to stdout */
static void callback( GtkWidget *widget, gpointer data)
{
const gchar *entry_text1;
const gchar *entry_text2;
g_print ("Hello again - %s was pressed\n", (char *) data);
entry_text1 = gtk_entry_get_text (GTK_ENTRY (entry1));
entry_text2 = gtk_entry_get_text (GTK_ENTRY (entry2));
g_print ("Contents of entries:\n%s\n%s\n", entry_text1, entry_text2);
}
You should additionally make similar modifications to the enter_callback function, and don't forget to remove the GtkWidget pointers to both GtkEntry from main.
As an alternative to using (static) global variables, create a data structure to hold the entries:
typedef struct login_data
{
GtkWidget *entry1;
GtkWidget *entry2;
} login_data;
This then gets passed to the callback (rather than text string as before), and the callback changes like so:
static void callback( GtkWidget *widget, gpointer data)
{
login_data* ld = (login_data*)data;
const gchar *entry_text1;
const gchar *entry_text2;
entry_text1 = gtk_entry_get_text (GTK_ENTRY (ld->entry1));
entry_text2 = gtk_entry_get_text (GTK_ENTRY (ld->entry2));
g_print ("Contents of entries:\n%s\n%s\n", entry_text1, entry_text2);
}
The data structure is dynamically allocated to prevent it going out of scope (not strictly necessary in simple applications) and this is done before using g_signal_connect to connect the callback to the entries:
login_data* ld = g_malloc(sizeof(*ld));
// callback function to execute when login is clicked
g_signal_connect (LoginButton, "clicked", G_CALLBACK (callback), (gpointer) ld);
Using this method, you must change all references to entry1 and entry2 to ld->entry1 and ld->entry2. Lastly, before the program exits, you should call g_free on the dynamically allocated struct ie g_free(ld).
BTW, for this program you don't need two separate callbacks, remove enter_callback and just use callback for both.

gtktreeview works fine in the example but stops once copied into application

I have the following problem. I'm developing an application which uses gtktreeview for displaying data retrieved from MySQL database.
I've already done few examples of gtktreeview, I was able to add, clear, remove from the list. Now I wanted to adapt this example to my application and suddenly it doesn't work anymore.
Here is the example I used which works.
The enum:
static enum {
FIRST_NAME,
LAST_NAME,
N_COL
};
The variables:
static GtkWidget *list;
static GtkWidget *f_entry;
static GtkWidget *l_entry;
The setup of a list:
static GtkWidget *setup_list()
{
GtkWidget *sc_win;
GtkListStore *store;
GtkCellRenderer *cell;
GtkTreeViewColumn *column;
sc_win = gtk_scrolled_window_new(NULL, NULL);
gtk_widget_set_usize(sc_win, 250, 150);
store = gtk_list_store_new(N_COL, G_TYPE_STRING, G_TYPE_STRING);
list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
cell = gtk_cell_renderer_text_new();
// column of the names
column = gtk_tree_view_column_new_with_attributes("Imię", cell, "text", FIRST_NAME, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);
// column of the surnames
column = gtk_tree_view_column_new_with_attributes("Nazwisko", cell, "text", LAST_NAME, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);
// scrolls
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sc_win), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
gtk_container_add(GTK_CONTAINER(sc_win), list);
// free the store variable and return the scrolled window pointer
g_object_unref(G_OBJECT(store));
return sc_win;
}
The function which adds an element:
static void list_add_cb(GtkWidget* widget, gpointer data)
{
GtkListStore *store;
GtkTreeIter iter;
const char *first;
const char *last;
first = gtk_entry_get_text(GTK_ENTRY(f_entry));
last = gtk_entry_get_text(GTK_ENTRY(l_entry));
store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(list)));
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter, FIRST_NAME, first, LAST_NAME, last, -1);
}
And here is the equivalent in my application.
The enum:
enum {
ID_ALIAS,
N_COL
};
The variables (only those significant for the example):
static GtkWidget *list_pas;
static GtkWidget *list_key;
The setup of a list (almost identycle, except of passing the column name in the parameter and usage of only one column):
static GtkWidget *setup_list(char *typ)
{
GtkWidget *sc_win;
GtkWidget *list;
GtkListStore *store;
GtkCellRenderer *cell;
GtkTreeViewColumn *column;
sc_win = gtk_scrolled_window_new(NULL, NULL);
gtk_widget_set_usize(sc_win, 250, 150);
store = gtk_list_store_new(N_COL, G_TYPE_STRING, G_TYPE_STRING);
list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
cell = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes(typ, cell, "text", ID_ALIAS, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);
// scrolls
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sc_win), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
gtk_container_add(GTK_CONTAINER(sc_win), list);
// free the store variable and return the scrolled window pointer
g_object_unref(G_OBJECT(store));
return sc_win;
}
The function which adds an element (in data there is a string of the element to add to the list and in the widget there is scrolled window which contains proper list):
static void list_add_cb(GtkWidget* widget, gpointer data)
{
GtkListStore *store;
GtkTreeIter iter;
store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(widget)));
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter, ID_ALIAS, (char *) data*, -1);
}
It does not work because of following errors I get everytime MySQL function tryes to write the data in their fields:
(app_0:3642): GLib-GObject-WARNING **: invalid cast from `GtkScrolledWindow' to `GtkTreeView'
(app_0:3642): Gtk-CRITICAL **: IA__gtk_tree_view_get_model: assertion `GTK_IS_TREE_VIEW (tree_view)' failed
(app_0:3642): Gtk-CRITICAL **: IA__gtk_list_store_append: assertion `GTK_IS_LIST_STORE (list_store)' failed
(app_0:3642): Gtk-CRITICAL **: IA__gtk_list_store_set_valist: assertion `GTK_IS_LIST_STORE (list_store)' failed
Here is how the function of adding a row is called:
list_add_cb(list, row[i] ? row[i] : "NULL");
I will also say that when I printf the row[i] ? row[i] : "NULL" I get correct value.
The MySQL part of my application works more than fine. The only warning I get while compilation is useless class storage specifier in empty declaration which I researched and here on stackoverflow.com I have learned this has nothing to do with this problem.
The other difference is I'm creating mutliple lists in my application. To verify if this was the source of the problem I have deleted all the lists except one single list and this changed nothing.
I've been also trying to charge the list with input fields and a button trigger, but this hasn't change anything. I've also tryed reordering declarations of the variables with the enum this had none effect on the result neither.
I haven't found anything usefull, I'm out of ideas, please help. I've been trying to explain this as clearly as possible, please ask question and correct me and my post. Thanks.
I've found the solution. Unfortunately I don't know exactly why it solves the problem.
As user ntd said in the comment I used GtkScrolledWindow to append lists, I though it's ok because it was this way in the example, but in the example there were secondary variables, not global in the main function which I didn't noticed. So thank you ntd for your point.
Second thing came of using multiple lists. The function static GtkWidget *setup_list(char *typ) had to be doubled. The funny thing was that I couldn't pass the gtktreeview object in the argument of this function, but once I've created two functions setup_list(char *typ) and setup_list2(char *typ) where the only difference was a variable used for storing gtktreeview.
I don't really know why it does work this way, I'll be happy to learn if someone has an idea. I'm happy anyway because my project can go further now. Cheers people!

What's the GTK header I need to include so I can use lookup_widget?

As shown in the example below, this callback function is when the user clicks an OK button. I can get window (the top level widget) from button by using gtk_widget_get_toplevel, but I'm stuck trying to get a widget pointer for a GtkEntry widget with name ENTRY.
/* Called when OK button is clicked */
on_BT_OK_clicked(GtkButton *button, gpointer user_data)
{
//The line directly below is the one I get an error on
GtkWidget *entry = lookup_widget( GTK_WIDGET(button), "ENTRY" );
gchar *text1, *text2;
text1 = gtk_entry_get_text( GTK_ENTRY(entry));
text2 = g_strconcat("Hello, ", text1, NULL);
GtkWidget *window = gtk_widget_get_toplevel (GTK_WIDGET(button));
GtkWidget *dialog = gtk_message_dialog_new( window,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_INFO,
GTK_BUTTONS_CLOSE,
text2);
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
}
But I get the error "undefined reference to lookup_widget." I can find a billion examples of snippets of code using lookup_widget, but not a single one full source code example showing the headers that enable the use of it. I'm using Anjuta3.2.0 and the latest Glade plugin.
As Basile Starynkevitch says, lookup_widget() was a function generated by Glade 2. However, code generation by Glade has been deprecated for quite a long time now, in favor of (first) libglade and (later) GtkBuilder. In fact, Glade 3 won't even do it.
The preferred solution is to pass a pointer to your ENTRY as the user data pointer when you connect the signal, or, if you're using gtk_builder_connect_signals(), store a pointer to ENTRY in your class and pass the class as the user data pointer.
However, if you must use lookup_widget(), here's the source that Glade 2 generated as of about 6 years ago:
GtkWidget*
lookup_widget (GtkWidget *widget,
const gchar *widget_name)
{
GtkWidget *parent, *found_widget;
for (;;)
{
if (GTK_IS_MENU (widget))
parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
else
parent = widget->parent;
if (!parent)
parent = (GtkWidget*) g_object_get_data (G_OBJECT (widget), "GladeParentKey");
if (parent == NULL)
break;
widget = parent;
}
found_widget = (GtkWidget*) g_object_get_data (G_OBJECT (widget),
widget_name);
if (!found_widget)
g_warning ("Widget not found: %s", widget_name);
return found_widget;
}
For this to work, you have to do the following for every widget contained within a toplevel window:
g_object_set_data_full (G_OBJECT (toplevel), "name-of-widget", gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref);
and then the following once for each toplevel window:
g_object_set_data (G_OBJECT (toplevel), "name-of-toplevel", toplevel);
Seems to me to be more trouble than it's worth.
Glade-2 implements lookup_widget() in support.c and the header is support.h
Once the GLADE GUI is converted to C codes these files are generated automatically.

Resources