Search code examples
ctimergtk

GTK Timer - How to make a timer within a frame


How do g_timer_new works?

is it possible to do a

char timerz[50];

GTimer *timer


g_timer_start(GTimer *timer);

strcpy(timerz,(g_timer_elapsed(GTimer *timer))

Or what Could I do to have a timer in a gtk_frame???

Have a nice day! :D


Solution

  • You can use g_timeout_add or g_timeout_add_seconds which will call a timeout function at regular interval. Please note that this timeout function can be delayed due to event processing and should not be relied on for precise timing. Check this developer page for more info on main loop.
    Here is an example to get you started (you can improvise over this). In the example the timeout is set in seconds thus using g_timeout_add_seconds, use g_timeout_add if you need millisecond precision.

    #include <stdio.h>
    #include <string.h>
    #include <gtk/gtk.h>
    
    /* Determines if to continue the timer or not */
    static gboolean continue_timer = FALSE;
    
    /* Determines if the timer has started */
    static gboolean start_timer = FALSE;
    
    /* Display seconds expired */
    static int sec_expired = 0;
    
    static void
    _quit_cb (GtkWidget *button, gpointer data)
    {
        (void)button; (void)data; /*Avoid compiler warnings*/
        gtk_main_quit();
        return;
    }
    
    
    static gboolean
    _label_update(gpointer data)
    {
        GtkLabel *label = (GtkLabel*)data;
        char buf[256];
        memset(&buf, 0x0, 256);
        snprintf(buf, 255, "Time elapsed: %d secs", ++sec_expired);
        gtk_label_set_label(label, buf);
        return continue_timer;
    
    }
    
    static void
    _start_timer (GtkWidget *button, gpointer data)
    {
        (void)button;/*Avoid compiler warnings*/
        GtkWidget *label = data;
        if(!start_timer)
        {
            g_timeout_add_seconds(1, _label_update, label);
            start_timer = TRUE;
            continue_timer = TRUE;
        }
    }
    
    static void
    _pause_resume_timer (GtkWidget *button, gpointer data)
    {
        (void)button;/*Avoid compiler warnings*/
        if(start_timer)
        {
            GtkWidget *label = data;
            continue_timer = !continue_timer;
            if(continue_timer)
            {
                g_timeout_add_seconds(1, _label_update, label);
            }
            else
            {
                /*Decrementing because timer will be hit one more time before expiring*/
                sec_expired--;
            }
        }
    }
    
    static void
    _reset_timer (GtkWidget *button, gpointer data)
    {
        (void)button; (void)data;/*Avoid compiler warnings*/
        /*Setting to -1 instead of 0, because timer will be triggered once more before expiring*/
        sec_expired = -1;
        continue_timer = FALSE;
        start_timer = FALSE;
    }
    
    int main(void)
    {
        GtkWidget *window;
        GtkWidget *vbox;
        GtkWidget *start_button;
        GtkWidget *pause_resume_button;
        GtkWidget *reset_button;
        GtkWidget *quit_button;
        GtkWidget *label;
    
        gtk_init(NULL, NULL);
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        g_signal_connect (G_OBJECT (window), "destroy", 
                        G_CALLBACK (gtk_main_quit),
                        NULL);
        vbox = gtk_vbox_new (FALSE, 2);
        gtk_container_add(GTK_CONTAINER(window), vbox);
    
        label = gtk_label_new("Time elapsed: 0 secs");
    
        start_button = gtk_button_new_with_label("Start");
        g_signal_connect(G_OBJECT(start_button), "clicked", G_CALLBACK(_start_timer), label);
    
        pause_resume_button = gtk_button_new_with_label("Pause/Resume");
        g_signal_connect(G_OBJECT(pause_resume_button), "clicked", G_CALLBACK(_pause_resume_timer), label);
    
        reset_button = gtk_button_new_with_label("Reset");
        g_signal_connect(G_OBJECT(reset_button), "clicked", G_CALLBACK(_reset_timer), label);
    
        quit_button = gtk_button_new_with_label("Quit");
        g_signal_connect(G_OBJECT(quit_button), "clicked", G_CALLBACK(_quit_cb), NULL);
    
        gtk_box_pack_start (GTK_BOX(vbox), label, 0, 0, 0);
        gtk_box_pack_start (GTK_BOX(vbox), start_button, 0, 0, 0);
        gtk_box_pack_start (GTK_BOX(vbox), pause_resume_button, 0, 0, 0);
        gtk_box_pack_start (GTK_BOX(vbox), reset_button, 0, 0, 0);
        gtk_box_pack_start (GTK_BOX (vbox), quit_button, 0, 0, 0);
    
        gtk_widget_show_all(window);
    
        g_timeout_add_seconds(1, _label_update, label);
        continue_timer = TRUE;
        start_timer = TRUE;
    
        gtk_main();
        return 0;
    }
    

    Hope this helps!