3

In virtually every example code of GTK+ I've seen so far, the widgets of the GUI are all defined inside the main function. At first I adopted this, but then found it highly inconvenient when e.g. manipulating multiple widgets from a single callback function. Of course I could just use the 'data' gpointer for that, but wouldn't I have to wrap every widget I want to manipulate in some sort of struct first to pass it as the 'data' argument?

Anyway, to not be bound by this, I just started defining all Widgets outside the main function, so I can easily access them across all function. Are there any drawbacks to this style?

1 Answer 1

2

The drawbacks are the same as the drawbacks for using any global variable. This page has a good overview of situations when you should not (and when you should) use global variables. If you look near the bottom, you will see under "Really bad reasons to use global variables":

I don't want to pass it around all the time.

I'm afraid this is kind of what your objection sounds like. However, as the page I linked to also mentions, if you are just writing short or one-off programs, then the ease of using global variables probably outweighs the drawbacks.

The usual way in medium-sized programs is to create a struct and populate it in main(), and pass it to the callbacks:

typedef struct {
    GtkWidget *window, *button, *textfield;
} Widgets;

int main(int argc, char **argv) {
    gtk_init(&argc, &argv);
    Widgets *w = g_slice_new0(Widgets);
    w->window = gtk_window_new(... etc...
    ...
    g_signal_connect(w->button, "clicked", G_CALLBACK(on_clicked), w);
    ...etc...
    gtk_main();
    g_slice_free(Widgets, w);
    return 0;
}

In large programs, a better way is to create your own classes representing main windows, preferences dialogs, etc., and pass those classes to the various callbacks.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for the response! I guess at the end of the day the easiest way to kind of make both sides happy is to, just as you suggested, put every single widget from the very start in one big struct and then pass that around each time. (Although, what to do if I need both widgets and signal handler id? Seems like widgets would always block the 'gpointer userdata')
There's nothing preventing you from putting a signal handler ID in the struct too.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.