1

I have a simple GTK4 C program that displays a dropdown with 3 choices and a label. The callback for the dropdown notify::selected-item event passes the label as the 2nd argument. The callback is attempting to retrieve the selection from the dropdown and change the label to some new text saying the dropdown selection changed. When the program is run and a new selection is made in the dropdown, 2 CRITICAL errors are displayed in the terminal window, and, obviously, the program does not work. I do not see what I have done wrong. Can anyone spot something obvious? Here are the errors from the terminal window:

Selected item index: 1

(dropdown:7896): GLib-GObject-CRITICAL **: 16:52:49.770: invalid cast from 'GParamObject' to 'GtkLabel'

(dropdown:7896): Gtk-CRITICAL **: 16:52:49.771: gtk_label_set_text: assertion 'GTK_IS_LABEL (self)' failed

Here is the code:

/*
 * dropdown.c
 *
 * Description:
 *   Demonstrates use of GTK4 dropdown widget. A dropdown widget and a label
 *   widget in a vbox. When a selection is made in the dropdown, the selection
 *   text is displayed in the label.
 */

#include <gtk/gtk.h>

static void on_window_destroy(GtkWidget *widget, gpointer data)
{
    g_application_quit(G_APPLICATION(data));
}

static void on_dropdown_changed(GtkWidget *widget, gpointer data)
{
    GtkDropDown *dd = GTK_DROP_DOWN(widget);

    printf("Selected item index: %d\n", gtk_drop_down_get_selected(dd));

    gtk_label_set_text(GTK_LABEL(data), "Dropdown changed");
}

static void activate(GtkApplication *app, gpointer user_data)
{
    GtkWidget *window;
    GtkWidget *vbox;
    GtkWidget *lbl_choice;
    GtkWidget *dropdown_str;

    window = gtk_application_window_new(app);
    gtk_window_set_title(GTK_WINDOW(window), "GTK4 DropDown Demo");
    gtk_window_set_default_size(GTK_WINDOW(window), 300, -1);
    g_signal_connect(window, "destroy", G_CALLBACK(on_window_destroy), app);

    vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
    gtk_box_set_homogeneous(GTK_BOX(vbox), true);
    gtk_window_set_child(GTK_WINDOW(window), vbox);

    const char* const dropdown_choices[] = {"Steak", "Fish", "Chicken", NULL};
    dropdown_str = gtk_drop_down_new_from_strings(dropdown_choices);
    gtk_box_append(GTK_BOX(vbox), dropdown_str);

    lbl_choice = gtk_label_new_with_mnemonic("No selection yet");
    gtk_box_append(GTK_BOX(vbox), lbl_choice);

    g_signal_connect(dropdown_str, "notify::selected-item",
                     G_CALLBACK(on_dropdown_changed), lbl_choice);

    gtk_window_present(GTK_WINDOW(window));
}

int main(int argc, char **argv)
{
    GtkApplication *app;
    int status;

    app = gtk_application_new("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
    g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
    status = g_application_run(G_APPLICATION(app), argc, argv);
    g_object_unref(app);

    return status;
}
1

1 Answer 1

1

Change signature of function

static void on_dropdown_changed(GtkWidget *widget, gpointer data)

to

static void on_dropdown_changed(GtkWidget *widget, GParamSpec *specs, gpointer data)

and try again.

Link for the docs about notify signal on GObject https://docs.gtk.org/gobject/signal.Object.notify.html

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

1 Comment

Yes, this is the solution. I have not seen a callback with this argument list before.

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.