问题
I'm trying to update a label with an integer value depending on whether I press a subtract or add button. Its not working however and I'm pretty sure it has something to do with how I pass my GTK_LABEL(sum) around, and the int I'm trying to update into it.
What worked before was passing an address to the int to the button function, and then g_printing it into the terminal, via the best answer to this question.
Here is the full error message, and here's my code so far.
#include <gtk/gtk.h>
#include <string.h>
void updateLabel(GTK_LABEL(sum), int num)
{
gchar *display;
display = g_strdup_printf("%d", num); //convert num to str
gtk_label_set_text (GTK_LABEL(sum), display); //set label to "display"
g_free(display); //free display
}
void buttonAdd (GtkButton *button, GtkLabel *sum, gpointer num)
{
num += 1;
g_print("%i\n",num);
updateLabel(GTK_LABEL(sum),num);
}
void buttonSub (GtkButton *button, GtkLabel *sum, gpointer num)
{
num -= 1;
g_print("%i\n",num);
updateLabel(GTK_LABEL(sum),num);
}
int main (int argc, char **argv)
{
signed int n = 0;
char display = n;
GtkWidget *window;
GtkWidget *addButton;
GtkWidget *subButton;
GtkWidget *grid;
GtkWidget *sum;
gtk_init (&argc,&argv);
//Declarations
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
sum = gtk_label_new (&display);
grid = gtk_grid_new ();
addButton = gtk_button_new_with_label ("Add Value");
subButton = gtk_button_new_with_label ("Sub Value");
//Set Properties
gtk_container_set_border_width (GTK_CONTAINER(window), 20);
gtk_widget_set_size_request (GTK_CONTAINER(window), 150, 100);
gtk_label_set_selectable (GTK_LABEL(sum), TRUE);
gtk_grid_set_row_spacing (GTK_GRID(grid), 4);
gtk_grid_set_column_spacing (GTK_GRID(grid), 4);
gtk_container_add (GTK_CONTAINER(window), grid);
//Fill the grid with shit (x, y, h, v)
gtk_grid_attach (GTK_GRID(grid), addButton, 0, 0, 1, 1);
gtk_grid_attach (GTK_GRID(grid), subButton, 1, 0, 1, 1);
gtk_grid_attach (GTK_GRID(grid), sum, 0, 2, 2, 1);
gtk_widget_show_all (window);
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(G_OBJECT(addButton), "clicked", G_CALLBACK(buttonAdd), &n);
g_signal_connect(G_OBJECT(subButton), "clicked", G_CALLBACK(buttonSub), &n);
gtk_main();
return 0;
}
I think its important to note that I'm new to C, and I come from python, so pointers, addresses, and GTK syntax is pretty cryptic to me. Simple non-jargony GTK guides also seem to not exist on the internet yet too. If someone could show me what I'm doing wrong or a show a better way that would be awesome!! Thanks!
回答1:
I modified your code to work as you described:
#include <gtk/gtk.h>
#include <string.h>
#include <stdlib.h>
void updateLabel(GtkLabel *sum, int num)
{
gchar *display;
display = g_strdup_printf("%d", num); //convert num to str
gtk_label_set_text (GTK_LABEL(sum), display); //set label to "display"
g_free(display); //free display
}
void buttonAdd (GtkButton *button, GtkLabel *sum)
{
int num = atoi(gtk_label_get_text(sum));
num += 1;
g_print("%d\n",num);
updateLabel(GTK_LABEL(sum), num);
}
void buttonSub (GtkButton *button, GtkLabel *sum)
{
int num = atoi(gtk_label_get_text(sum));
num -= 1;
g_print("%i\n",num);
updateLabel(GTK_LABEL(sum),num);
}
int main(int argc, char **argv)
{
GtkWidget *window;
GtkWidget *addButton;
GtkWidget *subButton;
GtkWidget *grid;
GtkWidget *sum;
gtk_init (&argc,&argv);
//Declarations
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
sum = gtk_label_new ("0");
grid = gtk_grid_new ();
addButton = gtk_button_new_with_label ("Add Value");
subButton = gtk_button_new_with_label ("Sub Value");
//Set Properties
gtk_container_set_border_width (GTK_CONTAINER(window), 20);
gtk_widget_set_size_request (GTK_WIDGET(window), 150, 100);
gtk_label_set_selectable (GTK_LABEL(sum), TRUE);
gtk_grid_set_row_spacing (GTK_GRID(grid), 4);
gtk_grid_set_column_spacing (GTK_GRID(grid), 4);
gtk_container_add (GTK_CONTAINER(window), grid);
//Fill the grid with shit (x, y, h, v)
gtk_grid_attach (GTK_GRID(grid), addButton, 0, 0, 1, 1);
gtk_grid_attach (GTK_GRID(grid), subButton, 1, 0, 1, 1);
gtk_grid_attach (GTK_GRID(grid), sum, 0, 2, 2, 1);
gtk_widget_show_all (window);
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(G_OBJECT(addButton), "clicked", G_CALLBACK(buttonAdd), sum);
g_signal_connect(G_OBJECT(subButton), "clicked", G_CALLBACK(buttonSub), sum);
gtk_main();
return 0;
}
From the beginning:
Although a char can be used as an int, you cannot convert a whole int to string simply by
char display = n;
as each char has it's own value associated with a character they represent (http://www.asciitable.com/). A string (char * or char[]) is made of a table of chars.Button's signal function
buttonAdd()
andbuttonSub
contains two parameters and not three: the first is a pointer of the gtk widget that caused the signal and the second parameter is a pointer passed in the last parameter fromg_signal_connect()
function. Normally we'd have a lot of data to pass trough the pointer so in that case we'd make a struct variable, fill it and pass that through, but in your case it's enough to just pass the gtk label, because it already contains the string which we can read and increase/decrease it.I used atoi() to convert the string to int, but for a more robust solution it's better to use strtol, but for your example atoi() is more than enough.
You cannot use GTK_LABEL() as a parameter, because it's a macro and not a type.
来源:https://stackoverflow.com/questions/26429173/getting-a-gtk-label-to-dislay-an-int-in-c