在不使用按钮的情况下使用 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;
}
只需编译并尝试一下,您就会发现您的应用程序不会干扰您的标签,即使您单击该按钮也是如此。
我正在做一个显示用户 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;
}
只需编译并尝试一下,您就会发现您的应用程序不会干扰您的标签,即使您单击该按钮也是如此。