Interfacce grafiche per i nostri programmi in GTK+ – parte 1 –

Negli ultimi anni siamo stati testimoni di un notevole incremento della complessità ed allo stesso tempo bellezza delle interfacce grafiche dei software che usiamo come anche del Sistema Operativo che abbiamo installato sul nostro calcolatore. In questa guida, che per comodità dividerò in più parti, ho pensato di proporvi un sistema per realizzare interfacce semplici ma allo stesso tempo potenti ed in alcuni casi ottime dal punto di vista della leggerezza in termini di costi di elaborazione. Il Gimp Tool Kit, noto come G.T.K., è una libreria scritta in linguaggio C che emula una organizzazione Object Oriented,   includendola nei nostri codici sorgente potremo costruire dei widget  (oggetti) grafici che assemblati secondo semplici regole andranno a costituire l’interfaccia grafica ai nostri programmi.

Prepariamo l’ambiente di sviluppo su Debian

Prima di tutto scaricate dal sito www.gtk.org i seguenti pacchetti :

glib-2.16.0.tar.gz
pango-1.20.0.tar.gz
gtk+-2.12.0.tar.gz

Ora li scompattiamo e poi procediamo alla loro compilazione, in questo modo :

# sudo ./configure --prefix=/usr
# sudo make
# sudo make install

solo per il pacchetto GTK+ l’installazione dovrà essere fatta con il comando:

# sudo ./configure --prefix=/usr --without-libtiff --without-libjpeg

Nel caso doveste incontrare problemi durante l’installazione è consigliabile aggiornare o semplicemente installare i seguenti pacchetti dai repository di Debian:

# sudo apt-get install build-essential libncurses5-dev 

Oppure semplicemente installare dai repository ufficiali del vostro sistema Linux il seguente pacchetto (senza compilare il tutto come sopra):    

# sudo apt-get install libgtk2.0-dev

A questo punto il nostro sistema è pronto, o quasi, infatti ci mancano gli strumenti per poter scrivere i nostri programmi in sorgente (C o C++). La scelta ricade su un tool molto diffuso e potente : l’editor di testo :-), infatti basta uno qualsiasi di quelli già conosciuti come : gedit, kwrite oppure vi o nano.

Oltre all’editor di testo non occorrerebbe nulla, uso il condizionale perchè per compilare il nostro programma in C avremo bisogno di un comando strutturato così come segue :

#sudo gcc -Wall -g nome_file.c -o nome-file.c.run `pkg-config --cflags gtk+-2.0` `pkg-config --libs gtk+-2.0`

A questo punto è chiaro che un altro “strumento di sviluppo” sarà uno script in bash più che altro utile ad evitarci di dover ridigitare, ogni volta, comandi molto lunghi e fortemente affettibili da errore. Ecco come è composto lo script, che vi consiglio di copiare ed incollare in un file che chiameremo : compila.sh

#!/bin/sh
gcc -Wall -g $1 -o $1.run `pkg-config --cflags gtk+-2.0` `pkg-config --libs gtk+-2.0`
./$1.run

ricordiamoci di renderlo eseguibile per tutti:

#sudo chmod ugo+x compila.sh

seguendo questa procedura ed utilizzando lo script appena creato  compileremo ed eseguiremo direttamente e con facilità ogni programma realizzato con le GTK+, ad esempio in questo modo :

#./compila.sh  < nome_file.c >

La nostra prima interfaccia GTK

A questo punto tutto è pronto per realizzare la nostra prima interfaccia. Per comodità commenterò le righe di codice scritte direttamente all’interno del codice sorgente in modo che, in seguito, rileggendo i nostri programmi ricorderemo i passi eseguiti. In linguaggio C i commenti si possono scrivere in due modi :
preceduti da // se il commento è su di una sola riga
preceduti da /* e seguiti da */ se il commento si sviluppa su più righe

Come ho detto in precedenza, il nostro ambiente di sviluppo sarà l’editor di testo quindi lanciamolo e scriviamo:

/* Includiamo la libreria che ci permette di usare e creare i nostri oggetti in GTK+ tra cui la finestra. */

#include <gtk/gtk.h>
/* Da questo punto in poi inizia il nostro programma. */
int main (int argc, char *argv[])
{
/* Inizializzo i miei oggetti, creando un oggetto di tipo Widget e lo chiameremo window. */
GtkWidget *window;
/* Inizializziamo GTK+ e tutte le librerie da lui supportate. */
gtk_init (&argc, &argv);
/* Creiamo la finestra con i tasti di chiusura, minimizza e massimizza se volevamo il solo frame dovevamo utilizzare la voce GTK_WINDOW_POPUP. */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
/* Diamo un titolo alla nostra finestra. */
gtk_window_set_title (GTK_WINDOW (window), "WINDOW");
/* Le diamo una dimensione (in pixel) fissa se si mette -1 e -1 la finestra assumerà le dimensioni a seconda degli oggetti in essa creati. */
gtk_widget_set_size_request (window, 200, 100);
/* Non diciamo altro che visualizzarla. */
gtk_widget_show_all (window);
/* Controllo delle GTK+ nel loop del nostro programma. */
gtk_main ();
return 0;
}

Salviamo il tutto in un file denominato finestra.c e procediamo alla compilazione e all’esecuzione della nostra finestra:

#./compila.sh finestra.c

Ed ecco la nostra finestra in GTK+ – figura 1 -, per chiuderla basterà cliccare sulla X ma, come vedremo, a terminale il processo non viene terminato saremo dunque costretti a chiuderlo con la combinazione di tasti CTRL+C.

Image

Ecco così la nostra prima finestra in GTK+!!!

Chiudere un processo dall’interfaccia

Abbiamo appena scoperto che per terminare il processo che ha generato l’interfaccia, siamo stati costretti a digitare Ctrl + c. In realtà possiamo ovviare a questo inserendo all’interno del nostro codice una parte che gestirà questo tipo di evento; Al momento della chiusura della finestra dovremo inviare un segnale che interromperà il processo ad essa associata.

#include <gtk/gtk.h>

/* Funzione che gestisce il segnale di destroy la X. */
static void destroy (GtkWidget*, gpointer);
/* Funzione che ci permetterà di gestire l'eventuale conferma di chiusura della finestra. */
static gboolean delete_event (GtkWidget*, GdkEvent*, gpointer);

int main (int argc, char *argv[])
{
GtkWidget *window;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "WINDOW");
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
gtk_widget_set_size_request (window, 200, 100);
/* Connettiamo la nostra finestra al segnale di destroy e di delete_event dove il nostro oggetto è la nostra finestra il segnale che è in ascolto è il destroy e qualora dovesse arrivare verrà eseguita la funzione associata alla callback. */
g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (destroy), NULL);
g_signal_connect (G_OBJECT (window), "delete_event", G_CALLBACK (delete_event), NULL);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}

/* Stoppiamo il loop del nostro programma fermando il tutto. */
static void destroy (GtkWidget *window, gpointer data)
{
gtk_main_quit ();
}

/* Se restituisce FALSE distruggiamo la finestra, mentre se restituiamo TRUE possiamo fare in modo da annulare la chiusura della nostra finestra. */
static gboolean delete_event (GtkWidget *window, GdkEvent *event, gpointer data)
{
return FALSE;
}

In questa maniera oltre alla chiusura della finestra sarà chiuso il processo ad essa associato liberando la memoria.

Da ora in poi, questa sarà sempre la base di partenza di tutte le nostre nuove applicazioni!!!