Allo stesso tempo si è offerto allo sviluppatore un potente e completo framework per la progettazione e costruzione di applicazioni basate su standard oramai affermati e facilmente integrabili con i più diffusi linguaggi di programmazione attualmente disponibili nel mondo Unix.
Gnome e Gtk sono nate per creare uno standard free (open source) per scrivere applicazioni grafiche uniformi per sistemi UNIX.
Chiunque può usare le librerie Gtk e la infrastruttura Gnome senza dover pagare diritti o sottostare a vincoli dei produttori.
Visto il rapido sviluppo di questi strumenti ho deciso di scrivere un paio di articoli in materia corredati da un tutorial integralmente in italiano che traduce e riassume essenzialmente quello ufficiale fornito a corredo delle librerie: Spesso vi è una gran confusione tra Gnome e Gtk+ e non appare a molti chiaro il rapporto in cui si pongono l'uno rispetto all'altro.
In questo breve articolo tratto essenzialmente dal noto libro di Havoc Pennington "Gtk+/Gnome Application Development" cercheremo di chiarire un po' i concetti di base sperando di sciogliere almeno qualche dubbio sull'argomento.
Abbiamo già visto che per creare un widget esiste l'apposita funzione gtk_nomedelwidget_new().
Per creare una finestra useremo quindi:
GtkWidget* window;
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
Tuttavia il widget anche se viene creato non è ancora visibile. Per renderlo visibile dobbiamo usare la funzione:
void gtk_widget_show( GtkWidget *widget );
Mentre per renderlo invisibile potremo usare:
void gtk_widget_hide( GtkWidget *widget );
Per settare la dimensione iniziale della finestra useremo:
void gtk_window_set_default_size(GtkWindow* window,
gint width,
gint height);
Per assegnargli una posizione specifica:
void gtk_widget_set_uposition(GtkWidget *widget,
gint x,
gint y );
Se invece la vogliamo al centro dello schermo:
void gtk_window_set_position (GtkWidget *widget,
GTK_WIN_POS_CENTER);
Per assegnargli un nome:
void gtk_widget_set_name(GtkWidget *widget,
gchar *name);
Se vogliamo assegnargli il Fuoco:
void gtk_widget_grab_focus(GtkWidget *widget);
Se vogliamo rendere il widget attivo/inattivo:
void gtk_widget_set_sensitive( GtkWidget *widget,
gboolean setting);
Infine per distruggere un widget:
void gtk_widget_destroy( GtkWidget* widget);
Bottoni.
Il Gtk+ ci mette a disposizione varie specie di bottoni: normal buttons, toggle buttons, check buttons e radio buttons.
Normal Buttons.
Ci sono due modi per creare un nuovo bottone:
Si può usare gtk_button_new_with_label() per creare un bottone con una label (etichetta) oppure gtk_button_new() per creare un bottone vuoto.
In tal caso per inserire una label o una pixmap nel bottone bisogna creare un contenitore e poi inserire la label o la pixmap nel contenitore con gtk_box_pack_start e gtk_container_add.Toggle Buttons.
I toggle buttons sono derivati dai normal buttons e sono molto simili eccettuato per il fatto che possono stare alternativamente in due stati: premuto o non-premuto.
I toggle buttons sono la base per i check buttons e i radio buttons cosicché molte chiamate sono comuni.
Per creare un nuovo toggle button useremo:
GtkWidget *gtk_toggle_button_new( void );
GtkWidget *gtk_toggle_button_new_with_label( gchar *label );
Come è facile immaginare queste chiamate funzionano esattamente come quelle relative ai normal buttons.
Per ricavare lo stato in cui si trova il toggle button (e ciò vale anche per i check buttons ed i radio buttons) si può usare una Macro come mostrato nell'esempio che segue.
Questa testa lo stato del bottone in una callback. Il segnale che ci interessa in questo caso è "toggled".
La callback assumerà la seguente forma:
void toggle_button_callback (GtkWidget *widget, gpointer data)
{
if (GTK_TOGGLE_BUTTON (widget)->active)
{
/* Se si arriva qui il bottone e' premuto */
} else {
/* Se si arriva qui il bottone è non-premuto */
}
}
La seguente chiamata può invece essere usata per settare lo stato di un toggle button (ma anche dei check e radio button).
void gtk_toggle_button_set_active( GtkToggleButton *toggle_button,
gint state );
Il primo argomento è il puntatore al nostro bottone ed il secondo può assumere la forma di TRUE (premuto) o FALSE (non-premuto).
L'ultima chiamata serve ad esercitre un "toggled" sul bottone che è ciò che accade quando clikkiamo con il mouse su di esso.
void gtk_toggle_button_toggled (GtkToggleButton *toggle_button);Check Buttons.
I Check buttons hanno molte funzioni e proprietà dei toggle button da cui derivano direttamente.
Sono in pratica delle piccole caselle con un'etichetta a lato che vengono usate nelle applicazioni per settare le opzioni su on/off.
Le due funzioni per la loro creazione sono simili a quelle degli altri bottoni:
GtkWidget *gtk_check_button_new( void );
GtkWidget *gtk_check_button_new_with_label ( gchar *label );
La funzione new_with_label crea appunto un check button con un'etichetta.
Rilevare lo stato di un checkbutton è identico a quanto abbiamo visto prima per i toggle button ed useremo le stesse funzioni.Radio Buttons.
I Radio buttons sono simili ai check button tranne per il fatto che sono raggruppati in gruppo e sono uno del gruppo può essere selezionato/premuto alla volta.
Questo è comodo quando abbiamo una lista di opzioni delle quali può essere attivata solo una.
Per creare un radio button useremo le solite funzioni:
GtkWidget *gtk_radio_button_new( GSList *group );
GtkWidget *gtk_radio_button_new_with_label( GSList *group,
gchar *label );
Come però si può notare vi è un argomento in più. La creazione del bottone richiede infatti un puntatore al gruppo.
La prima chiamata (creazione primo radio button) dovrà avere come argomento NULL.
Dopo aver creato il primo radio button si potrà creare il gruppo con:
GSList *gtk_radio_button_group( GtkRadioButton *radio_button );
Passando cioè a questa funzione il puntatore al primo bottone creato.
La cosa importante da creare è che gtk_radio_button_group deve essere chiamato per ogni nuovo radio button che si aggiunge al gruppo passandogli come argomento il bottone precedentemente creato.
L'esempio che seguirà illustra bene il meccanisno.
Il tutto comunque può essere fatto in modo più breve usando la seguente sintassi (in tal caso ad es. creiamo un terzo bottone):
button2 = gtk_radio_button_new_with_label(
gtk_radio_button_group (GTK_RADIO_BUTTON (button1)),
"button2");
E' anche una buona idea specificare quale bottone deve essere attivo di default con:
void gtk_toggle_button_set_active( GtkToggleButton *toggle_button,
gint state );
ESEMPIO#include <gtk/gtk.h>
#include <glib.h>
void close_application( GtkWidget *widget,
GdkEvent *event,
gpointer data )
{
gtk_main_quit();
}
int main( int argc,
char *argv[] )
{
GtkWidget *window = NULL;
GtkWidget *box1;
GtkWidget *box2;
GtkWidget *button;
GtkWidget *separator;
GSList *group;
gtk_init(&argc,&argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_signal_connect (GTK_OBJECT (window), "delete_event",
GTK_SIGNAL_FUNC(close_application),
NULL);
gtk_window_set_title (GTK_WINDOW (window), "radio buttons");
gtk_container_set_border_width (GTK_CONTAINER (window), 0);
box1 = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (window), box1);
gtk_widget_show (box1);
box2 = gtk_vbox_new (FALSE, 10);
gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
gtk_widget_show (box2);
button = gtk_radio_button_new_with_label (NULL, "button1");
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
gtk_widget_show (button);
group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
button = gtk_radio_button_new_with_label(group, "button2");
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
gtk_widget_show (button);
button = gtk_radio_button_new_with_label(
gtk_radio_button_group (GTK_RADIO_BUTTON (button)),
"button3");
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
gtk_widget_show (button);
separator = gtk_hseparator_new ();
gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
gtk_widget_show (separator);
box2 = gtk_vbox_new (FALSE, 10);
gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
gtk_widget_show (box2);
button = gtk_button_new_with_label ("close");
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC(close_application),
GTK_OBJECT (window));
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_widget_grab_default (button);
gtk_widget_show (button);
gtk_widget_show (window);
gtk_main();
return(0);
}
Ricerca personalizzata
Se ti è piaciuto l'articolo , iscriviti al feed cliccando sull'immagine sottostante per tenerti sempre aggiornato sui nuovi contenuti del blog: