Why is only left button updated with pictures and not up and right one?

Hi guys,
I have written little program i C with GTK3, so basically I have there button and I want to change pictures on them when I press left, up, or right key on keyboard, the issue is that what ever arrow I press the image is updated only on left arrow place holder. Here is my code

#include <gtk/gtk.h>

GtkWidget *button_l;
GtkWidget *button_r;
GtkWidget *button_up;
gboolean left_arrow_pressed = FALSE;
gboolean right_arrow_pressed = FALSE;
gboolean up_arrow_pressed = FALSE;

void set_button_icon(GtkWidget *button, const gchar *icon_name) {
    GdkPixbuf *icon = gdk_pixbuf_new_from_file(icon_name, NULL);
    if (icon == NULL) {
        g_printerr("Error loading image: %s\n", icon_name);
        return;
    }
    GtkWidget *image_widget = gtk_image_new_from_pixbuf(icon);
    gtk_button_set_image(GTK_BUTTON(button), image_widget);
}

gboolean on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data) {
    if (event->keyval == GDK_KEY_Left) {
        if (!left_arrow_pressed) {
            left_arrow_pressed = TRUE;
            g_print("Left arrow key pressed.\n");
        }
        set_button_icon(GTK_WIDGET(user_data), "pressed_icon_l.png");
        return TRUE; // Event handled
    } else if (event->keyval == GDK_KEY_Right) {
        if (!right_arrow_pressed) {
            right_arrow_pressed = TRUE;
            g_print("Right arrow key pressed.\n");
        }
        set_button_icon(GTK_WIDGET(user_data), "pressed_icon_r.png");
        return TRUE; // Event handled
    } else if (event->keyval == GDK_KEY_Up) {
        if (!up_arrow_pressed) {
            up_arrow_pressed = TRUE;
            g_print("Up arrow key pressed.\n");
        }
        set_button_icon(GTK_WIDGET(user_data), "pressed_icon_up.png");
        return TRUE; // Event handled
    }
    return FALSE; // Event not handled
}

gboolean on_key_release(GtkWidget *widget, GdkEventKey *event, gpointer user_data) {
    if (event->keyval == GDK_KEY_Left) {
        left_arrow_pressed = FALSE;
        set_button_icon(GTK_WIDGET(user_data), "initial_icon_l.png");
        return TRUE; // Event handled
    } else if (event->keyval == GDK_KEY_Right) {
        right_arrow_pressed = FALSE;
        set_button_icon(GTK_WIDGET(user_data), "initial_icon_r.png");
        return TRUE; // Event handled
    } else if (event->keyval == GDK_KEY_Up) {
        up_arrow_pressed = FALSE;
        set_button_icon(GTK_WIDGET(user_data), "initial_icon_up.png");
        return TRUE; // Event handled
    }
    return FALSE; // Event not handled
}

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

    gtk_init(&argc, &argv);

    builder = gtk_builder_new();
    gtk_builder_add_from_file(builder, "GladeUI_2.glade", NULL);
    gtk_builder_connect_signals(builder, NULL);

    window = GTK_WIDGET(gtk_builder_get_object(builder, "window1"));
    button_l = GTK_WIDGET(gtk_builder_get_object(builder, "button_l"));
    button_r = GTK_WIDGET(gtk_builder_get_object(builder, "button_r"));
    button_up = GTK_WIDGET(gtk_builder_get_object(builder, "button_up"));

    set_button_icon(button_l, "initial_icon_l.png");
    set_button_icon(button_r, "initial_icon_r.png");
    set_button_icon(button_up, "initial_icon_up.png");

    g_signal_connect(window, "key-press-event", G_CALLBACK(on_key_press), button_l);
    g_signal_connect(window, "key-release-event", G_CALLBACK(on_key_release), button_l);
    g_signal_connect(window, "key-press-event", G_CALLBACK(on_key_press), button_r);
    g_signal_connect(window, "key-release-event", G_CALLBACK(on_key_release), button_r);
    g_signal_connect(window, "key-press-event", G_CALLBACK(on_key_press), button_up);
    g_signal_connect(window, "key-release-event", G_CALLBACK(on_key_release), button_up);

    gtk_widget_show(window);
    gtk_main();

    g_object_unref(builder);

    return 0;
}

Here is my Glade file

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<interface>
  <requires lib="gtk+" version="3.24"/>
  <object class="GtkWindow" id="window1">
    <property name="can-focus">False</property>
    <child>
      <object class="GtkFixed" id="fixed1">
        <property name="visible">True</property>
        <property name="can-focus">False</property>
        <child>
          <object class="GtkButton" id="button_l">
            <property name="width-request">50</property>
            <property name="height-request">50</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="receives-default">True</property>
            <signal name="key-press-event" handler="on_button_l_pressed" swapped="no"/>
            <signal name="pressed" handler="on_button_l_pressed" swapped="no"/>
          </object>
          <packing>
            <property name="x">10</property>
            <property name="y">100</property>
          </packing>
        </child>
        <child>
          <object class="GtkButton" id="button_r">
            <property name="width-request">50</property>
            <property name="height-request">50</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="receives-default">True</property>
            <signal name="key-press-event" handler="on_button_r_pressed" swapped="no"/>
            <signal name="pressed" handler="on_button_r_pressed" swapped="no"/>
          </object>
          <packing>
            <property name="x">200</property>
            <property name="y">100</property>
          </packing>
        </child>
        <child>
          <object class="GtkButton" id="button_up">
            <property name="label" translatable="yes">
</property>
            <property name="width-request">50</property>
            <property name="height-request">50</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="receives-default">True</property>
            <signal name="key-press-event" handler="on_button_up_pressed" swapped="no"/>
            <signal name="pressed" handler="on_button_up_pressed" swapped="no"/>
          </object>
          <packing>
            <property name="x">100</property>
            <property name="y">50</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>

So when I press left arrow I have this

Left

But when I press UP arrow I have this

UP

But i need it to be in the middle, any suggestion ?

Glancing at it, the issue is probably that you return TRUE in your event handlers, but connect them several times. Returning TRUE means that you handled the event (you know that I see), and this leads to not processing further handlers for this event as it has already been dealt with.

What you should probably do is pass a container holding all your widgets to your handler and have it loop over them instead of trying to connect several times.

I have no idea how to write such code

You maybe want a tutorial like this one: GitHub - gdev-technology/glib-gtk-learning

It was written for GTK 3.

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