Ormai abbiamo visto tutto quello che c'è da vedere riguardo all'oggetto
``bottone''. E' piuttosto semplice, ma ci sono due modi per crare un bottone.
Potete usare gtk_button_new_with_label() per creare un bottone con una
etichetta, o usare gtk_button_new() per creare un bottone vuoto. In tal caso è poi
vostro compito impacchettare un'etichetta o una pixmap sul bottone creato.
Per fare ciò, create una nuova scatola, e poi impacchettateci i vostri
oggetti usando la solita gtk_box_pack_start, e infine usate la funzione
gtk_container_add per impacchettare la scatola nel bottone.
Ecco un esempio di utilizzo di gtk_button_new per creare un bottone con
un'immagine ed un'etichetta su di sè. Ho separato il codice usato per
creare la scatola in modo che lo possiate usare nei vostri programmi.
/* buttons.c */
#include <gtk/gtk.h>
/* crea una nuova hbox contenente un'immagine ed un'etichetta
* e ritorna la scatola creata. */
GtkWidget *xpm_label_box (GtkWidget *parent, gchar *xpm_filename, gchar *label_text)
{
GtkWidget *box1;
GtkWidget *label;
GtkWidget *pixmapwid;
GdkPixmap *pixmap;
GdkBitmap *mask;
GtkStyle *style;
/* creare una scatola per una xpm ed una etichetta */
box1 = gtk_hbox_new (FALSE, 0);
gtk_container_border_width (GTK_CONTAINER (box1), 2);
/* ottengo lo stile del bottone. Penso che sia per avere il colore
* dello sfondo. Se qualcuno sa il vero motivo, è pregato di dirmelo. */
style = gtk_widget_get_style(parent);
/* e ora via con le faccende dell'xpm stuff. Carichiamo l'xpm*/
pixmap = gdk_pixmap_create_from_xpm (parent->window, &mask,
&style->bg[GTK_STATE_NORMAL],
xpm_filename);
pixmapwid = gtk_pixmap_new (pixmap, mask);
/* creiamo l'etichetta per il bottone */
label = gtk_label_new (label_text);
/* impacchettiamo la pixmap e l'etichetta nella scatola */
gtk_box_pack_start (GTK_BOX (box1),
pixmapwid, FALSE, FALSE, 3);
gtk_box_pack_start (GTK_BOX (box1), label, FALSE, FALSE, 3);
gtk_widget_show(pixmapwid);
gtk_widget_show(label);
return (box1);
}
/* la nostra solita funzione di callback */
void callback (GtkWidget *widget, gpointer data)
{
g_print ("Hello again - %s was pressed\n", (char *) data);
}
int main (int argc, char *argv[])
{
/* GtkWidget è il tipo per contenere gli oggetti */
GtkWidget *window;
GtkWidget *button;
GtkWidget *box1;
gtk_init (&argc, &argv);
/* creiamo una nuova finestra */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Pixmap'd Buttons!");
/* E' una buona idea fare questo per tutte le finestre. */
gtk_signal_connect (GTK_OBJECT (window), "destroy",
GTK_SIGNAL_FUNC (gtk_exit), NULL);
gtk_signal_connect (GTK_OBJECT (window), "delete_event",
GTK_SIGNAL_FUNC (gtk_exit), NULL);
/* assegnamo lo spessore del bordo della finestra */
gtk_container_border_width (GTK_CONTAINER (window), 10);
gtk_widget_realize(window);
/* creiamo un nuovo bottone */
button = gtk_button_new ();
/* Ormai dovreste esservi abituati a vedere la maggior parte di
* queste funzioni */
gtk_signal_connect (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (callback), (gpointer) "cool button");
/* questa chiama la nostra funzione di creazione di scatole */
box1 = xpm_label_box(window, "info.xpm", "cool button");
/* impacchetta e mostra tutti i nostri oggetti */
gtk_widget_show(box1);
gtk_container_add (GTK_CONTAINER (button), box1);
gtk_widget_show(button);
gtk_container_add (GTK_CONTAINER (window), button);
gtk_widget_show (window);
/* mettiti in gtk_main e aspetta che cominci il divertimento! */
gtk_main ();
return 0;
}
La funzione xpm_label_box può essere usata per impacchettare delle xpm
e delle etichette su qualsiasi oggetto che può essere un contenitore.
I bottoni a commutazione sono molto simili ai bottoni normali, tranne che per il
fatto che essi si trovano sempre in uno di due stati, che si alternano ad ogni
click. Possono trovarsi nello stato ``premuto'', e quando li si ripreme, tornano
ad essere sollevati. Ri-clickandoli, torneranno giù.
I bottoni a commutazione sono la base per i bottoni di controllo (check button) e
per i radio-bottoni, e quindi molte delle chiamate disponibili per i bottoni
a commutazione vengono ereditati dai radio-bottoni e dai bottoni di controllo.
Ma vedremo questi aspetti nel momento in cui li incontreremo.
Come potete immaginare, queste funzioni lavorano in modo identico che per
i bottoni normali. La prima crea un bottone a commutazione vuoto e la seconda un
bottone con un'etichetta.
Per ottenere lo stato dei widget a commutazione, compresi i radio-bottoni e i
bottoni di controllo, si può usare una macro come mostrato nell'esempio
più sotto. In questo modo lo stato dell'oggetto commutabile viene valutato in
una funzione di ritorno. Il segnale emesso dai bottoni a commutazione
(toggle button, il radio button o il check button) che ci interessa è il segnale
``toggled''. Per controllare lo stato di questi bottoni, create un gestore di
segnali che catturi il ``toggled'', e usate la macro per determinare
il suo stato. La funzione di callback avrà un aspetto più o meno così:
void toggle_button_callback (GtkWidget *widget, gpointer data)
{
if (GTK_TOGGLE_BUTTON (widget)->active)
{
/* Se il programma si è arrivato a questo punto, il bottone
* a commutazione è premuto */
} else {
/* il bottone è sollevato */
}
}
La chiamata qui sopra può essere usata per fare l'assegnazione dello stato
del bottone a commutazione e dei suoi figli, il radio-bottone e il bottone di
controllo. Passando come primo argomento a questa funzione il vostro bottone e
come secondo argomento il valore TRUE o FALSE, si può specificare se il
bottone deve essere sollevato (rilasciato) o abbassato (premuto). Il valore
di difetto è sollevato, cioè FALSE.
Notate che quando usate la funzione gtk_toggle_button_set_state(), e lo
stato viene cambiato, si ha il risultato che il bottone emette il segnale
``clicked''.
I bottoni di controllo ereditano molte proprietà e funzioni dal bottone a commutazione,
ma hanno un aspetto un po' diverso. Invece di essere bottoni contenenti del testo,
si tratta di quadratini con del testo alla propria destra. Questi bottoni sono
spesso usati nelle applicazioni per commutare fra lo stato attivato e disattivato delle
opzioni.
Le due funzioni di creazione sono analoghe a quelle del bottone normale..
I radio-bottoni sono simili ai bottoni di controllo, tranne che per il
fatto che sono sempre raggruppati in modo che solo uno alla volta di essi
può essere selezionato (premuto). Tornano utili quando nella propria applicazione
si ha bisogno di selezionare una opzione da una breve lista.
La creazione di un nuovo radio-bottone si fa con una di queste chiamate:
Avrete notato l'argomento in più che c'è in queste chiamate. Queste hanno
infatti bisogno dela specificazione di un ``gruppo'' per svolgere il loro compito.
Per il primo bottone di un gruppo si deve passare come primo argomento il valore
NULL. Dopodiché potete creare un gruppo usando la funzione:
La cosa importante da ricordare è che gtk_radio_button_group va chiamata ogni volta che si aggiunge un nuovo bottone al gruppo, con il preceente bottone passato come argomento. Il risultato viene poi passato nella chiamata a gtk_radio_button_new o a gtk_radio_button_new_with_label. Ciò permette di creare una catena di bottoni. L'esempio più sotto dovrebbe chiarire questo punto.
E' poi una buona idea stabiire quale dev'essere il bottone premuto per difetto, usando: