Find the answer to your Linux question:
Results 1 to 4 of 4
Hi there, I want to write a GUI in GTK, which means i need several of the buttons to perform certain functions. However, i can't figure out how the callback ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    May 2005
    Posts
    2

    GTK callback help


    Hi there,

    I want to write a GUI in GTK, which means i need several of the buttons to perform certain functions. However, i can't figure out how the callback functions work. The way i'm making the calculator is this:

    I have a boolean which checks to see which of the two "registers" (in this case, they're just strings) i'm using, and then when a button is pressed, it'll add a character on to the end of the string. This is how my buttons look, this one is for the number 1:

    button = gtk_button_new ();
    g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "1");
    gtk_table_attach_defaults (GTK_TABLE (table), button, 0, 1, 4, 5);
    box = xpm_label_box ("1.jpg");
    gtk_widget_show (box);
    gtk_container_add (GTK_CONTAINER (button), box);
    gtk_widget_show (button);
    And i'm not sure how to make the callback

    Right now, it just looks like this
    void callback( GtkWidget *widget, gpointer data )
    {
    g_print ("%s", (gchar *) data);
    }
    As you can see, there's nothing in it yet, because i don't know how to proceed.

    So my question is 2 fold

    1) how do i get the callback to check the appropriate boolean, "boolean register1", which exists in my main, and tells me if i should be using register1 or not. Do i need to add a second signal connect statement to my button that sends a pointer to the boolean, or is that possible?

    2) How do i get the GUI to return that string to the screen, which is a label in the GUI?

  2. #2
    Linux User
    Join Date
    Jul 2004
    Location
    Poland
    Posts
    368
    Hello

    1) Callbacks are just usual functions that get called by the GTK by means of pointers to them. Therefore the usual C variable scoping rules adhere. To solve the problem you should perhaps make the variables to be accessible by the callback global, or pass a pointer to them as data parameter of g_signal_connect. It is possible to have multiple callbacks for a single event, but, in practice, if you want to pass multiple variables to a single callback create a structure and pass an instance of it as data parameter.

    2) Use gtk_label_set(ptr_to_label, "text to be displayed"). Of course you have to have the pointer to the label accessible.

    Hope this explanation helps a little. If you want me to clarify something, go on and write...
    "I don't know what I'm running from
    And I don't know where I'm running to
    There's something deep and strange inside of me I see"

  3. #3
    Just Joined!
    Join Date
    May 2005
    Posts
    2
    Hi Kyku,

    i'm very much new to C, so i'm not really comfortable with its ins and outs of it yet. You were right about the global variables, i was declaring them in my main, when i should have been declaring outside everything. It turns out i really don't need to do the rest, seen as this is sorted. However, If you could break it down the rest a little more for me, i'd really appreciate it.

    Basically, how do i set a pointer to the label so that its accessible inside my
    callback function? And do i have to then pass it in the signal? This may be a very basic question, but i haven't really covered that yet.

  4. #4
    Linux User
    Join Date
    Jul 2004
    Location
    Poland
    Posts
    368
    I've created a working sample for you:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <gtk/gtk.h>
    
    // Pointers to widgets that we'll be operating with in the callbacks.
    static
    GtkWidget *label, *entry;
    
    static
    gboolean on_delete_event &#40;GtkWidget *widget, GdkEvent *event, gpointer data&#41;
    &#123;
      gtk_main_quit&#40;&#41;;
      return FALSE;
    &#125;
    
    static
    void on_button_click &#40;GtkWidget *widget, gpointer data&#41;
    &#123;
      // Retrieve the contents of the label and print it.
      const char *old_text = gtk_label_get_text &#40;GTK_LABEL &#40;label&#41;&#41;;
      g_print &#40;"Old label text&#58; %s\n", old_text&#41;;
      // Now change it to entry's contents.
      const char *text = gtk_entry_get_text &#40;GTK_ENTRY &#40;entry&#41;&#41;;
      gtk_label_set_text &#40;GTK_LABEL &#40;label&#41;, text&#41;;
    &#125;
    
    int main &#40;int argc, char *argv&#91;&#93;&#41;
    &#123;
      gtk_init &#40;&argc, &argv&#41;;
    
      GtkWidget *window = gtk_window_new &#40;GTK_WINDOW_TOPLEVEL&#41;;
      g_signal_connect &#40;G_OBJECT &#40;window&#41;, "delete_event",
        G_CALLBACK&#40;on_delete_event&#41;, NULL&#41;;
      gtk_window_set_title &#40;GTK_WINDOW &#40;window&#41;, "A sample program"&#41;;
    
      // Create a box and set is as window's main child.
      GtkWidget *box = gtk_vbox_new&#40;FALSE, 10&#41;;
      gtk_container_add &#40;GTK_CONTAINER&#40;window&#41;, box&#41;;
    
      // Now add label entry and a button.
      // Store pointers of the relevant ones &#40;i.e. entry and label&#41;
      // in global variables.
      label = gtk_label_new &#40;"Enter some text below and press the button"&#41;;
      gtk_box_pack_start &#40;GTK_BOX &#40;box&#41;, label, TRUE, TRUE, 5&#41;;
      entry = gtk_entry_new &#40;&#41;;
      gtk_box_pack_start &#40;GTK_BOX &#40;box&#41;, entry, TRUE, TRUE, 5&#41;;
      GtkWidget *button = gtk_button_new_with_label &#40;"Rewrite"&#41;;
      gtk_box_pack_start &#40;GTK_BOX &#40;box&#41;, button, TRUE, TRUE, 5&#41;;
      g_signal_connect &#40;G_OBJECT &#40;button&#41;, "clicked",
        G_CALLBACK &#40;on_button_click&#41;, NULL&#41;;
      gtk_widget_show_all &#40;window&#41;;
      gtk_main &#40;&#41;;
      return EXIT_SUCCESS;
    &#125;
    Save as label.c and compile with:
    Code:
    gcc -Wall -o label `pkg-config --cflags --libs gtk+-2.0` label.c

    I simply declare ptr to label as a global variable and next rewrite the entry
    text to the label. Simple but educating
    "I don't know what I'm running from
    And I don't know where I'm running to
    There's something deep and strange inside of me I see"

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •