在不使用按钮的情况下使用 C 更新 GTK 文本标签

Update a GTK text label with C without using buttons

我正在做一个显示用户 CPU 温度的 C GUI 应用程序,因此我添加了一个文本标签来显示温度。但我不确定如何更新标签。 如果在 gtk_main() 之前调用更新标签的函数(使用 while 循环,不断更新温度),应用程序将无法启动,因为它卡在函数的循环中。如果在 gtk_main() 之后调用它,则不会更新标签。

这里是 print_temperature() 函数:

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);
    }
      
}

有人可以帮我吗?我还在学习C.

好吧,问题不在于你怎么做,而在于,你知道你到底想做什么吗?

我仍然不是 100% 理解您的程序,但据我了解,您有一个应每 n 秒更新一次温度标签的应用程序。

我会用 g_timeout_add 传递你的函数,像这样:

#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;
}

只需编译并尝试一下,您就会发现您的应用程序不会干扰您的标签,即使您单击该按钮也是如此。