I’m learning gtk4 in C. I’m trying to do a simple number base conversion program. The actual number conversion logic is just a placeholder, right now I just want to get the gtk stuff to work.
#include <gtk/gtk.h>
#include <stdlib.h>
void convert_number(GtkWidget *widget, gpointer user_data) {
GtkWidget **widgets = (GtkWidget **)user_data;
GtkWidget *entry = widgets[0];
GtkWidget *combo_box_from = widgets[1];
GtkWidget *combo_box_to = widgets[2];
GtkWidget *label = widgets[3];
const gchar *number_str = gtk_editable_get_text(GTK_EDITABLE(entry));
int base_from = gtk_drop_down_get_selected(GTK_DROP_DOWN(combo_box_from));
int base_to = gtk_drop_down_get_selected(GTK_DROP_DOWN(combo_box_to));
char *endptr;
long number = strtol(number_str, &endptr, base_from);
if (*endptr != '\0') {
gtk_label_set_text(GTK_LABEL(label), "Invalid number");
return;
}
char result[33];
snprintf(result, sizeof(result), "%ld", number);
gtk_label_set_text(GTK_LABEL(label), result);
}
void activate(GtkApplication *app, gpointer user_data) {
GtkWidget *window = gtk_application_window_new(app);
gtk_window_set_title(GTK_WINDOW(window), "Conversor de bases");
gtk_window_set_default_size(GTK_WINDOW(window), 200, 200);
GtkWidget *grid = gtk_grid_new();
GtkWidget *entry = gtk_entry_new();
gtk_entry_set_placeholder_text(GTK_ENTRY(entry), "Digite um número");
gtk_editable_set_editable(GTK_EDITABLE(entry), TRUE);
GtkStringList *list_from = gtk_string_list_new(NULL);
GtkStringList *list_to = gtk_string_list_new(NULL);
GtkWidget *button = gtk_button_new_with_label("Converter");
const gchar *bases[] = {"Binario", "Octal", "Decimal", "Hexadecimal"};
for (int i = 0; i < 4; i++) {
gtk_string_list_append(list_from, bases[i]);
gtk_string_list_append(list_to, bases[i]);
}
GtkWidget *combo_box_from = gtk_drop_down_new(G_LIST_MODEL(list_from), NULL);
GtkWidget *combo_box_to = gtk_drop_down_new(G_LIST_MODEL(list_to), NULL);
GtkWidget *label = gtk_label_new("");
GtkWidget *widgets[] = {entry, combo_box_from, combo_box_to, label};
g_signal_connect(button, "clicked", G_CALLBACK(convert_number), widgets);
gtk_grid_attach(GTK_GRID(grid), entry, 0, 0, 1, 1);
gtk_grid_attach(GTK_GRID(grid), combo_box_from, 0, 1, 1, 1);
gtk_grid_attach(GTK_GRID(grid), combo_box_to, 0, 2, 1, 1);
gtk_grid_attach(GTK_GRID(grid), button, 0, 3, 1, 1);
gtk_grid_attach(GTK_GRID(grid), label, 0, 4, 1, 1);
gtk_window_set_child(GTK_WINDOW(window), grid);
gtk_window_present(GTK_WINDOW(window));
}
int main(int argc, char *argv[]) {
GtkApplication *app = gtk_application_new("gtk.example.app", G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
int status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);
return status;
}
Everything renders fine, but after I type a number and select the base I want to convert from and the base I want to convert to and click the convert button I get a segfault.
It seems to happen on line 11
const gchar *number_str = gtk_editable_get_text(GTK_EDITABLE(entry));
If I add
if (!GTK_IS_EDITABLE(entry)) {
return;
}
It segfaults there
What am I doing wrong?