How to store GtkWidget variable in an array? C

, ,

I am currently learning C and GTK to develop GUI applications.

I want to store multiple GtkWidget variables inside an array.

I created multiple global GtkWidget variables like so

GtkWidget *exVar1;
GtkWidget *exVar2;

In my main function, I connected them to UI objects from builder like so.

exVar1 = GTK_WIDGET(gtk_builder_get_object(builder, "exUIObj"));

I want to store the exVars in a global array for easy access.

Creating a global GtkWidget exArray[len] variable and added each of them inside resulted in the following error message when attempting to compile for each element in the variable.

main.c:84:2: warning: initialization of ‘GTypeClass *’ {aka ‘struct _GTypeClass *’} from incompatible pointer type ‘GtkWidget *’ {aka ‘struct _GtkWidget *’} [-Wincompatible-pointer-types]
   84 |  button0,
      |  ^~~~~~~
main.c:84:2: note: (near initialization for ‘buttons[0].parent_instance.g_type_instance.g_class’)
main.c:84:2: error: initializer element is not constant
main.c:84:2: note: (near initialization for ‘buttons[0].parent_instance.g_type_instance.g_class’)
main.c:85:2: warning: initialization of ‘unsigned int’ from ‘GtkWidget *’ {aka ‘struct _GtkWidget *’} makes integer from pointer without a cast [-Wint-conversion]

What is the correct way to create and store GtkWidget variables in an array?

Hi! :slight_smile:

That sounds like a bad idea. I mean, if there’s multiple different widgets, then they surely have different use so they should be stored in a struct separately with identifying names, such as “increment_button” or “message_label”.

If you use an array then you’ll likely not want to hardcode the indexes to e.g. 2 or 0, so you’ll start using an enumeration to index it. Except it would just end up being a reimplementation of structs in a less straightforward way.

Anyway, without your full code (including your array declaration) it’s gonna be difficult to help much here with regards to the error message.

If you mean a global variable which is an array, then that’s not a very good idea because it means you won’t be able to have multiples instances of your custom widget. The normal way of doing this is subclassing the widget, where you’ll be able to store it in your widget’s private struct.

At the end of the day, if you really need to store them in a variable then

GtkWidget *buttonA = my_button_new();
GtkWidget *labelA = my_label_new();
GtkWidget *labelB = my_label_new();
GtkWidget *widgets_array[] = {buttonA, labelA, labelB};

Should compile fine.

There isn’t anything different from how you’d do it with e.g. strings:

int main()
{
    char *foobar = "foobar";
    char *baz = "baz";
    char *h = "h";
    char *arr[] = {foobar, baz, h};
    for (int i = 0; i < sizeof(arr)/sizeof(arr[0]); i++)
        printf("%s\n", arr[i]);

    return 0;
}
3 Likes

And the recommended way of doing that is using templates: GtkWidget: GTK+ 3 Reference Manual

3 Likes

If you want an array of pointers, you need to declare it like this:

GtkWidget *my_widgets[5];

What you have:

GtkWidget my_widgets[5];

Is an array of GtkWidget structs, not an array of pointers.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.