user46573544
user46573544

Reputation: 147

How to use g_timeout_add?

I am making a program in C with GTK and Glade for a serial communication. I am having problem using g_timeout_add. For example I have a function serial_data() which contain my serial data and I have a button handler on_update_button_clicked(). So till now I have done that if update button is clicked, gtk_timeout should run. But it running just for one time.

on_update_button_clicked(GtkButton *Update_Button)
{
     //2nd argument is serial_data function which contain actual data    
     g_timeout_add(250,serial_data,NULL); 
}

where I am missing the point?

I have another button stop button. So i want that timeout should stop when stop button handler is clicked. How to do that.??

One more question to ask, I want to count the number of times timeout is running like a counter. So that I can display the numbers of counter. How is this possible.? Please help thanks.

Upvotes: 3

Views: 23213

Answers (3)

jackw11111
jackw11111

Reputation: 1547

From the documentation, The function is called repeatedly until it returns FALSE. You can call on_update_button with a boolean argument to toggle the timeout call from being continually called, set it running when argument evaluates to TRUE, and delete the thread with g_source_remove(threadID) if argument is FALSE. Here's a demonstration:

// compiling with:  gcc test.c `pkg-config --cflags gtk+-3.0` `pkg-config --libs gtk+-3.0` -o test
#include <stdio.h>
#include <gtk/gtk.h>
#include <glib/gi18n.h>

guint threadID = 0;
guint serial_counter = 0;

static gboolean
serial_data (gpointer user_data)
{
    // do something
    printf("counter: %d\n", serial_counter);
    serial_counter++;
    return user_data;
}

static void
on_update_button_clicked (GtkButton* button, gpointer user_data)
{
    if (user_data == 1)
    {
        threadID = g_timeout_add(250, serial_data, user_data);
    }
    else if (user_data == 0)
    {
        g_source_remove(threadID);
        threadID = 0;   
    }
}

int
main (int argc, char *argv[])
{
    GtkWidget *window;
    gtk_init (&argc, &argv);
    GtkWidget *update_button;
    GtkWidget *stop_button;
    GtkWidget *box;

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title (GTK_WINDOW (window), "test.c");

    box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);

    update_button = gtk_button_new_with_label (_("Update"));
    stop_button = gtk_button_new_with_label (_("Stop"));

    gtk_box_pack_start (GTK_BOX (box), update_button, FALSE, FALSE, 0);
    gtk_box_pack_start (GTK_BOX (box), stop_button, FALSE, FALSE, 0);

    gtk_container_add (GTK_CONTAINER (window), box);

    g_signal_connect (update_button, "clicked", G_CALLBACK (on_update_button_clicked), 1);
    g_signal_connect (stop_button, "clicked", G_CALLBACK (on_update_button_clicked), 0);
    g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
    gtk_widget_show_all (window);

    gtk_main ();
    return 0;
}

Upvotes: 6

J Eti
J Eti

Reputation: 302

check the developer site

https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-timeout-add

its quite explicit.

you can have a gpointer to a gboolean STOP, finish the serial_data func in return STOP, and make your stop button change that STOP = FALSE and it will stop calling on that function. Or something like that.

Upvotes: 2

Jussi Kukkonen
Jussi Kukkonen

Reputation: 14577

g_timeout_add() returns an event source id that you should store. You can use g_source_remove() with that id in your stop button handler to stop the timeout.

Upvotes: 3

Related Questions