GTK+ (GIMP Toolkit) es un toolkit multiplataforma para crear interfaces gráficas de usuario (GUI) originalmente desarrollado para el programa GIMP.
sudo apt-get install libgtk-3-dev
sudo dnf install gtk3-devel
brew install gtk+3
Descargar MSYS2 desde msys2.org y luego:
pacman -S mingw-w64-x86_64-gtk3
// Compilar en Linux/macOS
gcc programa.c -o programa `pkg-config --cflags --libs gtk+-3.0`
// Compilar en Windows (MSYS2)
gcc programa.c -o programa.exe `pkg-config --cflags --libs gtk+-3.0`
#include <gtk/gtk.h>
// Función callback para el botón
static void on_button_clicked(GtkWidget *widget, gpointer data) {
g_print("¡Botón clickeado!\n");
}
int main(int argc, char *argv[]) {
// Inicializar GTK
gtk_init(&argc, &argv);
// Crear ventana principal
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Hola GTK+");
gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);
// Conectar señal "destroy" para cerrar la aplicación
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
// Crear un botón
GtkWidget *button = gtk_button_new_with_label("Presióname");
g_signal_connect(button, "clicked", G_CALLBACK(on_button_clicked), NULL);
// Añadir botón a la ventana
gtk_container_add(GTK_CONTAINER(window), button);
// Mostrar todos los widgets
gtk_widget_show_all(window);
// Bucle principal de GTK
gtk_main();
return 0;
}
GObject (base fundamental)
├── GInitiallyUnowned
│ └── GtkWidget (base para todos los widgets)
│ ├── GtkContainer (puede contener otros widgets)
│ │ ├── GtkBin (contiene un solo hijo)
│ │ │ ├── GtkWindow
│ │ │ ├── GtkButton
│ │ │ └── ...
│ │ ├── GtkBox (organización horizontal/vertical)
│ │ ├── GtkGrid (organización en cuadrícula)
│ │ └── ...
│ ├── GtkLabel (muestra texto)
│ ├── GtkEntry (entrada de texto)
│ └── ...
└── ...
GTK+ usa un sistema de señales y callbacks para manejar eventos:
// Conectar una señal a un callback
g_signal_connect(widget, "signal-name", G_CALLBACK(callback_function), user_data);
// Ejemplo:
g_signal_connect(button, "clicked", G_CALLBACK(on_button_clicked), NULL);
#include <gtk/gtk.h>
int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);
// Crear ventana principal
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Ventana GTK+");
gtk_window_set_default_size(GTK_WINDOW(window), 400, 300);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
// Configurar borde
gtk_container_set_border_width(GTK_CONTAINER(window), 10);
// Conectar señal de cierre
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show(window);
gtk_main();
return 0;
}
#include <gtk/gtk.h>
void button_clicked(GtkWidget *widget, gpointer data) {
g_print("Botón %s presionado\n", (char*)data);
}
int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Botones GTK+");
// Crear caja vertical
GtkWidget *box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
gtk_container_add(GTK_CONTAINER(window), box);
// Crear botones
GtkWidget *button1 = gtk_button_new_with_label("Botón 1");
GtkWidget *button2 = gtk_button_new_with_label("Botón 2");
// Conectar señales
g_signal_connect(button1, "clicked", G_CALLBACK(button_clicked), "Uno");
g_signal_connect(button2, "clicked", G_CALLBACK(button_clicked), "Dos");
// Añadir botones a la caja
gtk_box_pack_start(GTK_BOX(box), button1, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(box), button2, TRUE, TRUE, 0);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
#include <gtk/gtk.h>
int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Etiquetas GTK+");
// Crear etiqueta
GtkWidget *label = gtk_label_new("¡Hola GTK+!");
// Configurar etiqueta
gtk_label_set_markup(GTK_LABEL(label),
"<span font='16' foreground='blue'>Texto formateado</span>");
gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
gtk_container_add(GTK_CONTAINER(window), label);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
#include <gtk/gtk.h>
void on_entry_activated(GtkEntry *entry, gpointer data) {
const gchar *text = gtk_entry_get_text(entry);
g_print("Texto ingresado: %s\n", text);
}
int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Entrada GTK+");
GtkWidget *entry = gtk_entry_new();
gtk_entry_set_placeholder_text(GTK_ENTRY(entry), "Escribe algo...");
gtk_entry_set_max_length(GTK_ENTRY(entry), 50);
g_signal_connect(entry, "activate", G_CALLBACK(on_entry_activated), NULL);
gtk_container_add(GTK_CONTAINER(window), entry);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
#include <gtk/gtk.h>
int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Cajas GTK+");
gtk_container_set_border_width(GTK_CONTAINER(window), 10);
// Crear caja vertical con espaciado de 5 píxeles
GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
// Añadir widgets a la caja
GtkWidget *label = gtk_label_new("Caja Vertical");
GtkWidget *button1 = gtk_button_new_with_label("Botón 1");
GtkWidget *button2 = gtk_button_new_with_label("Botón 2");
gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox), button1, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(vbox), button2, TRUE, TRUE, 0);
gtk_container_add(GTK_CONTAINER(window), vbox);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
#include <gtk/gtk.h>
int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Grid GTK+");
gtk_container_set_border_width(GTK_CONTAINER(window), 10);
// Crear grid
GtkWidget *grid = gtk_grid_new();
gtk_grid_set_row_spacing(GTK_GRID(grid), 5);
gtk_grid_set_column_spacing(GTK_GRID(grid), 5);
// Añadir widgets al grid
GtkWidget *label = gtk_label_new("Cuadrícula:");
gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 2, 1); // col 0, row 0, width 2, height 1
GtkWidget *button1 = gtk_button_new_with_label("Botón 1");
gtk_grid_attach(GTK_GRID(grid), button1, 0, 1, 1, 1);
GtkWidget *button2 = gtk_button_new_with_label("Botón 2");
gtk_grid_attach(GTK_GRID(grid), button2, 1, 1, 1, 1);
GtkWidget *button3 = gtk_button_new_with_label("Gran Botón");
gtk_grid_attach(GTK_GRID(grid), button3, 0, 2, 2, 1);
gtk_container_add(GTK_CONTAINER(window), grid);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
#include <gtk/gtk.h>
int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Pestañas GTK+");
// Crear notebook (pestañas)
GtkWidget *notebook = gtk_notebook_new();
// Crear páginas
GtkWidget *page1 = gtk_label_new("Contenido de la página 1");
GtkWidget *page2 = gtk_label_new("Contenido de la página 2");
// Añadir páginas al notebook
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page1, gtk_label_new("Pestaña 1"));
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page2, gtk_label_new("Pestaña 2"));
gtk_container_add(GTK_CONTAINER(window), notebook);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
#include <gtk/gtk.h>
enum {
COL_NAME = 0,
COL_AGE,
NUM_COLS
};
static GtkTreeModel* create_model(void) {
GtkListStore *store = gtk_list_store_new(NUM_COLS, G_TYPE_STRING, G_TYPE_INT);
// Añadir datos
GtkTreeIter iter;
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter, COL_NAME, "Juan Pérez", COL_AGE, 30, -1);
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter, COL_NAME, "María García", COL_AGE, 25, -1);
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter, COL_NAME, "Carlos López", COL_AGE, 35, -1);
return GTK_TREE_MODEL(store);
}
static void add_columns(GtkTreeView *treeview) {
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
// Columna Nombre
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes("Nombre", renderer,
"text", COL_NAME, NULL);
gtk_tree_view_append_column(treeview, column);
// Columna Edad
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes("Edad", renderer,
"text", COL_AGE, NULL);
gtk_tree_view_append_column(treeview, column);
}
int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "TreeView GTK+");
// Crear TreeView con modelo
GtkWidget *treeview = gtk_tree_view_new_with_model(create_model());
add_columns(GTK_TREE_VIEW(treeview));
// Añadir a ScrolledWindow
GtkWidget *scrolled = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_container_add(GTK_CONTAINER(scrolled), treeview);
gtk_container_add(GTK_CONTAINER(window), scrolled);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
#include <gtk/gtk.h>
void on_combo_changed(GtkComboBox *combo, gpointer data) {
gint active = gtk_combo_box_get_active(combo);
if (active >= 0) {
gchar *text = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(combo));
g_print("Seleccionado: %s\n", text);
g_free(text);
}
}
int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "ComboBox GTK+");
gtk_container_set_border_width(GTK_CONTAINER(window), 10);
// Crear ComboBoxText
GtkWidget *combo = gtk_combo_box_text_new();
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), "Opción 1");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), "Opción 2");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), "Opción 3");
g_signal_connect(combo, "changed", G_CALLBACK(on_combo_changed), NULL);
gtk_container_add(GTK_CONTAINER(window), combo);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
#include <gtk/gtk.h>
int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Editor de Texto");
gtk_window_set_default_size(GTK_WINDOW(window), 600, 400);
// Crear TextView
GtkWidget *textview = gtk_text_view_new();
GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
// Insertar texto inicial
gtk_text_buffer_set_text(buffer, "Escribe aquí tu texto...\n", -1);
// Configurar fuente
PangoFontDescription *font_desc = pango_font_description_from_string("Monospace 12");
gtk_widget_override_font(textview, font_desc);
pango_font_description_free(font_desc);
// Añadir a ScrolledWindow
GtkWidget *scrolled = gtk_scrolled_window_new(NULL, NULL);
gtk_container_add(GTK_CONTAINER(scrolled), textview);
gtk_container_add(GTK_CONTAINER(window), scrolled);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
#include <gtk/gtk.h>
#include <cairo.h>
gboolean on_draw(GtkWidget *widget, cairo_t *cr, gpointer data) {
// Configurar color de fondo
cairo_set_source_rgb(cr, 1, 1, 1); // Blanco
cairo_paint(cr);
// Dibujar un rectángulo
cairo_set_source_rgb(cr, 0.8, 0.2, 0.2); // Rojo
cairo_rectangle(cr, 50, 50, 100, 80);
cairo_fill(cr);
// Dibujar un círculo
cairo_set_source_rgb(cr, 0.2, 0.2, 0.8); // Azul
cairo_arc(cr, 200, 100, 40, 0, 2 * G_PI);
cairo_fill(cr);
// Dibujar texto
cairo_set_source_rgb(cr, 0, 0, 0); // Negro
cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size(cr, 16);
cairo_move_to(cr, 50, 180);
cairo_show_text(cr, "Dibujo con Cairo");
return FALSE;
}
int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Dibujo GTK+");
// Crear área de dibujo
GtkWidget *drawing_area = gtk_drawing_area_new();
gtk_widget_set_size_request(drawing_area, 300, 200);
// Conectar señal de dibujo
g_signal_connect(drawing_area, "draw", G_CALLBACK(on_draw), NULL);
gtk_container_add(GTK_CONTAINER(window), drawing_area);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
Función | Descripción |
---|---|
cairo_set_source_rgb() | Establece color (RGB) |
cairo_set_source_rgba() | Establece color con transparencia (RGBA) |
cairo_move_to() | Mueve el punto actual |
cairo_line_to() | Dibuja una línea |
cairo_rectangle() | Dibuja un rectángulo |
cairo_arc() | Dibuja un arco o círculo |
cairo_fill() | Rellena la figura actual |
cairo_stroke() | Dibuja el contorno de la figura |
#include <gtk/gtk.h>
#include <gtk/gtkfilechooser.h>
GtkWidget *textview;
GtkTextBuffer *buffer;
void open_file(GtkWidget *widget, gpointer data) {
GtkWidget *dialog = gtk_file_chooser_dialog_new("Abrir archivo",
GTK_WINDOW(data),
GTK_FILE_CHOOSER_ACTION_OPEN,
"_Cancelar", GTK_RESPONSE_CANCEL,
"_Abrir", GTK_RESPONSE_ACCEPT,
NULL);
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
gchar *contents;
gsize length;
if (g_file_get_contents(filename, &contents, &length, NULL)) {
gtk_text_buffer_set_text(buffer, contents, length);
g_free(contents);
}
g_free(filename);
}
gtk_widget_destroy(dialog);
}
void save_file(GtkWidget *widget, gpointer data) {
GtkWidget *dialog = gtk_file_chooser_dialog_new("Guardar archivo",
GTK_WINDOW(data),
GTK_FILE_CHOOSER_ACTION_SAVE,
"_Cancelar", GTK_RESPONSE_CANCEL,
"_Guardar", GTK_RESPONSE_ACCEPT,
NULL);
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
GtkTextIter start, end;
gtk_text_buffer_get_bounds(buffer, &start, &end);
gchar *text = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
g_file_set_contents(filename, text, -1, NULL);
g_free(text);
g_free(filename);
}
gtk_widget_destroy(dialog);
}
int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Editor de Texto");
gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);
// Crear barra de menú
GtkWidget *menubar = gtk_menu_bar_new();
GtkWidget *file_menu = gtk_menu_new();
GtkWidget *file_item = gtk_menu_item_new_with_label("Archivo");
GtkWidget *open_item = gtk_menu_item_new_with_label("Abrir");
GtkWidget *save_item = gtk_menu_item_new_with_label("Guardar");
GtkWidget *exit_item = gtk_menu_item_new_with_label("Salir");
gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), open_item);
gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), save_item);
gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), gtk_separator_menu_item_new());
gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), exit_item);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(file_item), file_menu);
gtk_menu_shell_append(GTK_MENU_SHELL(menubar), file_item);
// Conectar señales del menú
g_signal_connect(open_item, "activate", G_CALLBACK(open_file), window);
g_signal_connect(save_item, "activate", G_CALLBACK(save_file), window);
g_signal_connect(exit_item, "activate", G_CALLBACK(gtk_main_quit), NULL);
// Crear editor de texto
textview = gtk_text_view_new();
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
// Configurar fuente monoespaciada
PangoFontDescription *font_desc = pango_font_description_from_string("Monospace 12");
gtk_widget_override_font(textview, font_desc);
pango_font_description_free(font_desc);
// Crear ScrolledWindow
GtkWidget *scrolled = gtk_scrolled_window_new(NULL, NULL);
gtk_container_add(GTK_CONTAINER(scrolled), textview);
// Organizar widgets en caja vertical
GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0);
gtk_container_add(GTK_CONTAINER(window), vbox);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
#include <gtk/gtk.h>
#include <string.h>
#include <stdlib.h>
GtkWidget *display;
double current_value = 0;
char current_operation = 0;
void update_display() {
char text[32];
snprintf(text, sizeof(text), "%.10g", current_value);
gtk_entry_set_text(GTK_ENTRY(display), text);
}
void on_digit_clicked(GtkButton *button, gpointer data) {
const char *digit = gtk_button_get_label(button);
const char *current = gtk_entry_get_text(GTK_ENTRY(display));
if (strcmp(current, "0") == 0 && digit[0] != '.') {
gtk_entry_set_text(GTK_ENTRY(display), digit);
} else {
char new_text[32];
snprintf(new_text, sizeof(new_text), "%s%s", current, digit);
gtk_entry_set_text(GTK_ENTRY(display), new_text);
}
}
void on_operation_clicked(GtkButton *button, gpointer data) {
const char *op = gtk_button_get_label(button);
const char *current = gtk_entry_get_text(GTK_ENTRY(display));
double operand = atof(current);
if (current_operation) {
switch(current_operation) {
case '+': current_value += operand; break;
case '-': current_value -= operand; break;
case '*': current_value *= operand; break;
case '/': current_value /= operand; break;
}
} else {
current_value = operand;
}
current_operation = op[0];
update_display();
gtk_entry_set_text(GTK_ENTRY(display), "0");
}
void on_equals_clicked(GtkButton *button, gpointer data) {
const char *current = gtk_entry_get_text(GTK_ENTRY(display));
double operand = atof(current);
if (current_operation) {
switch(current_operation) {
case '+': current_value += operand; break;
case '-': current_value -= operand; break;
case '*': current_value *= operand; break;
case '/': current_value /= operand; break;
}
current_operation = 0;
update_display();
}
}
void on_clear_clicked(GtkButton *button, gpointer data) {
current_value = 0;
current_operation = 0;
gtk_entry_set_text(GTK_ENTRY(display), "0");
}
int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Calculadora GTK+");
gtk_container_set_border_width(GTK_CONTAINER(window), 10);
// Crear display
display = gtk_entry_new();
gtk_entry_set_alignment(GTK_ENTRY(display), 1); // Alinear a la derecha
gtk_entry_set_text(GTK_ENTRY(display), "0");
gtk_editable_set_editable(GTK_EDITABLE(display), FALSE);
// Crear botones
const char *buttons[] = {
"7", "8", "9", "/",
"4", "5", "6", "*",
"1", "2", "3", "-",
"0", ".", "=", "+",
"C"
};
// Crear grid para botones
GtkWidget *grid = gtk_grid_new();
gtk_grid_set_row_spacing(GTK_GRID(grid), 5);
gtk_grid_set_column_spacing(GTK_GRID(grid), 5);
// Añadir botones al grid
for (int i = 0; i < 16; i++) {
GtkWidget *button = gtk_button_new_with_label(buttons[i]);
gtk_widget_set_size_request(button, 50, 50);
if (i % 4 == 3) {
g_signal_connect(button, "clicked", G_CALLBACK(on_operation_clicked), NULL);
} else if (i == 14) {
g_signal_connect(button, "clicked", G_CALLBACK(on_equals_clicked), NULL);
} else {
g_signal_connect(button, "clicked", G_CALLBACK(on_digit_clicked), NULL);
}
gtk_grid_attach(GTK_GRID(grid), button, i % 4, i / 4, 1, 1);
}
// Botón Clear
GtkWidget *clear = gtk_button_new_with_label(buttons[16]);
gtk_widget_set_size_request(clear, 50, 50);
g_signal_connect(clear, "clicked", G_CALLBACK(on_clear_clicked), NULL);
gtk_grid_attach(GTK_GRID(grid), clear, 0, 4, 4, 1);
// Organizar widgets en caja vertical
GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
gtk_box_pack_start(GTK_BOX(vbox), display, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox), grid, TRUE, TRUE, 0);
gtk_container_add(GTK_CONTAINER(window), vbox);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}