Re: have you seen my widgets?



On Sun, 2005-02-20 at 11:39, handsome greg wrote:
ok, let me just say that i'm "getting by" by doing things the way i
am, but im more interested in the Right Way (tm) to do things
according to gtk.  say i have a window with a vbox with a notebook
with a page with a frame with a vbox with a combobox.  in my main
window's vbox, i also have packed a button that says "go."  now when
someone clicks "go" i want something to happen that deals with the
currently selected item in the combo box.  currently im using a
g_object_set_data "paper trail" to the combo box by essentially
nesting a reference to each level of widgets into the previous one if
that makes any sense.  that way i can get a pointer to the notebook
from the button and a pointer to the frame from the notebook and so on
until i find the combo box.  now, my app is actually a lot more
complex and i need to decide on a method of doing things asap before
it just gets outta control.  what are my alternatives (besides globals
- not just static because they have to span multiple objects) ???  is
there any way to just say combo =
get_freakin_combobox_button("comboname"); ?  is there even a way to
"name" widgets?  surely not everyone out there just keeps a pointer
hanging around globally to every widget they plan on using from some
other far away widget, right?

Glade uses some code that performs what you want.

It's implemented with the following set of functions/macros:

//////////// glade functions ////////////////////
#define GLADE_HOOKUP_OBJECT(component,widget,name) \
  g_object_set_data_full (G_OBJECT (component), name, \
    gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref)

#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \
  g_object_set_data (G_OBJECT (component), name, widget)

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 = 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;
}
//////////// glade functions end ////////////////////

Then you "bind" all widgets you want to one top level widget, and you
can pick any other widget by name with lookup_widget().

As example:

GtkWidget *dialog;
GtkWiget *label;
GtkWidget *entry;
GtkWidget *button;

// ... build the UI ....

GLADE_HOOKUP_OBJECT_NO_REF (dialog, dialog,"dialog");
GLADE_HOOKUP_OBJECT (dialog, label, "label");
GLADE_HOOKUP_OBJECT (dialog, entry, "entry");
GLADE_HOOKUP_OBJECT (dialog, button, "button");

////

Then with any of those "binded" widgets you can pick a pointer from one
to another by name, as example:

dialog = lookup_widget(entry, "dialog");
entry = lookup_widget(button, "entry");
button = lookup_widget(label, "button");
label = lookup_widget(button, "label");

... and so on ...
-- 
Iago Rubio



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