Gabriel Dias
Gabriel Dias

Reputation: 79

Update a GTK text label with C without using buttons

I'm doing a C GUI application that show the user's CPU Temperature, so I added a text label to show the Temperature. But I'm not sure how to update the label. If the function to update the label (with a while loop, to update constantly the temperature) is called before gtk_main(),the app just won't start, because it's stuck in the loop of the function. And if it's called after the gtk_main(), the label isn't updated.

Here is the print_temperature() function:

void print_temperature(GtkLabel *cpu_temp) {
    while(1) {
        int *allTemps = calloc(3, sizeof(int));
        allTemps = getTemperatures(measureTemperature());

        char *currentTemp = malloc(8 * sizeof(char));
        sprintf(currentTemp, "%d.0°C", allTemps[0]);
        free(allTemps);

        gtk_label_set_text(cpu_temp, currentTemp);
        free(currentTemp);
    }
      
}

Can anyone help me with that, please? I'm still learning C.

Upvotes: 1

Views: 617

Answers (1)

Michi
Michi

Reputation: 5297

Well, the thing is not about how you do it, but more about, do you know what you exactly try to do?

I am still not 100% that I am understanding your program, but from what I understand, is that you have an Application which should update your temperature label every n seconds.

Me I'll use the g_timeout_add passing your function, something like this:

#include <gtk/gtk.h>
#include <math.h>

static void on_clicked ( GtkWidget *button )
{
    g_return_if_fail ( GTK_IS_BUTTON ( button ) );

    /// ***
    static guint i = 0;

    /// ***
    g_print ( "You clicked the Button %u Times\n", ++i );
}

static gboolean print_temperature ( GtkWidget *temperature )
{
    /// *** If no Label don't run
    g_return_val_if_fail ( GTK_IS_LABEL ( temperature ), FALSE );

    /// ***
    static float temp    = 0.0;
    const float max_temp = 25.0;

    /// ***
    char *text;
    text = g_strdup_printf ( "%.2f", temp++ );

    /// ***
    gtk_label_set_label ( GTK_LABEL ( temperature ), text );

    //// ***
    g_print ( "Temperature: %s\n", text );

    /// *** Free the Text
    g_free ( text );

    /// *** once that temp rich 25 should start again
    if ( fabs ( temp - max_temp ) < 0.01f )
    {
        temp = 0.0;
    }

    /// ***
    return TRUE;
}

static void activate_clbk ( GtkApplication *application )
{
    GtkWidget *window;
    GtkWidget *box;;
    GtkWidget *button;
    GtkWidget *label;

    /// ***
    window = gtk_application_window_new   ( application );
    gtk_window_set_default_size ( GTK_WINDOW ( window ), 200, 200 );

    /// *** Create a box
    box = gtk_box_new ( GTK_ORIENTATION_VERTICAL, 10 );

    /// *** Create a button
    button = gtk_button_new_with_label ( "Click me" );

    /// ***
    g_signal_connect_swapped ( button, "clicked", G_CALLBACK ( on_clicked ), button );

    /// ***
    label = gtk_label_new ( "0" );

    /// *** Call it every 250 milliseconds
    g_timeout_add ( 250, G_SOURCE_FUNC ( print_temperature ), label );

    /// *** If you need it only in seconds use this one
    /// g_timeout_add_seconds ( 1, G_SOURCE_FUNC ( print_temperature ), label );

    /// *** GTK3
    gtk_container_add ( GTK_CONTAINER ( window ), box );

    /// ***
    gtk_box_pack_start ( GTK_BOX ( box ), button, 1, 1, 10 );

    /// ***
    gtk_box_pack_start ( GTK_BOX ( box ), label, 1, 1, 10 );

    /// ***
    gtk_widget_show_all ( window );

    /*
    /// *** GTK4
    gtk_window_set_child ( GTK_WINDOW ( window ), box );

    /// ***
    gtk_box_append ( GTK_BOX ( box ), button );

    /// ***
    gtk_box_append ( GTK_BOX ( box ), label );

    /// ***
    gtk_window_present ( GTK_WINDOW ( window ) );
    */
}

int main ( void )
{
    GtkApplication *application;
    gint status;

    /// ***
    application = gtk_application_new ( "this.is.my-nice.app", G_APPLICATION_FLAGS_NONE );

    /// ***
    g_signal_connect ( application, "activate", G_CALLBACK ( activate_clbk ), NULL );

    /// ***
    status = g_application_run ( G_APPLICATION ( application ), FALSE, NULL );

    /// ***
    g_object_unref ( application );
    return status;
}

Just compile it and try it, and you will see that your application does not interferes with your label, even if you click that Button.

Upvotes: 1

Related Questions