Re: [gtk-list] which way is better?



Aaron Walker wrote:

> I am kind of new to GTK+ programming, so please bear with me.  Would it
> be better to use global variables for Gtk widgets, and have all
> functions in that file use them, or create separate widgets for each
> function?

I find that using globals becomes unmaintainable very quickly.

I tend to allocate a structure for each window and pass the structure
pointer to every callback for that window. I also store the pointer in
the window's user data area.

Here's an example:

<code>
#include <gtk/gtk.h>

struct Window
{
    GtkWidget   *window;
    GtkWidget   *button;
};

static
void on_destroy( GtkObject *obj, gpointer data )
{
    struct Window *window = (struct Window*) data;
    g_free( window );
}

static
gint on_delete_event( GtkWidget *widget, GdkEventAny *event, gpointer
data )
{
    struct Window *window = (struct Window*) data;
    gtk_main_quit();
    return 0;
}

GtkWidget * window_new()
{
    struct Window *window = g_malloc0( sizeof(struct Window) );

    window->window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
    window->button = gtk_button_new_with_label( "Hi there!" );

    gtk_container_add( GTK_CONTAINER(window->window), window->button );

    gtk_widget_show( window->button );

    gtk_signal_connect(
        GTK_OBJECT(window->window), "destroy",
        (GtkSignalFunc) on_destroy,
        window
        );
    gtk_signal_connect(
        GTK_OBJECT(window->window), "delete_event",
        (GtkSignalFunc) on_delete_event,
        window
        );

    gtk_object_set_user_data( GTK_OBJECT(window->window), window );

    return window->window;
}

void window_set_button_label( GtkWidget *widget, const char *label )
{
    GtkWidget *button_label;

    struct Window *window = (struct Window*)
        gtk_object_get_user_data( GTK_OBJECT(widget) );

    button_label = GTK_BIN(window->button)->child;
    gtk_label_set_text( GTK_LABEL(button_label), label );
}

int main(int argc, char *argv[])
{
    GtkWidget   *window;

    gtk_init( &argc, &argv );
    window = window_new();
    window_set_button_label( window, "I'm a button" );

    gtk_widget_show( window );
    gtk_main();

    return 0;
}
</code>

This has a number of benefits:

  o main() knows nothing about the window apart from how to create and
    manipulate it.
  o you can put everything apart from main() in, say, window.c. window.h
    can then contain function prototypes for the non-static functions,
    window_new() and window_set_button_label().
  o you can create two windows i.e. call window_new() twice and not have
    to worry about the memory - you can't do that using globals.

Note that connecting to the GtkObject::destroy event is necessary to
avoid losing the memory allocated for the window's structure.

There are probably improvements that can be made to this but it works
ok. In particular, I'm not keen on using the user data stuff .

Hope this helps.

Cheers, Matt.

-- 
Matt Goodall             |  Isotek Electronics Ltd
email: mgg@isotek.co.uk  |  Claro House, Servia Road
Tel: +44 113 2343202     |  Leeds, LS7 1NL
Fax: +44 113 2342918     |  England



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