vai alla Homepage di Apogeonline

 



Cos'è OpenPress
Glossario
Linux-FAQ
Documenti:

Open Source Definition

GNU General Public License

La cattedrale e il bazaar

Colonizzare la noosfera

Il calderone magico


Libri:

Italian crackdown

Open Sources

MediaMorfosi

GTK+/GNOME
sviluppo applicazioni


Telematica per la pace

Linux HOWTO: Installazione e configurazione

Linux HOWTO: Networking


Risorse
Feedback
vai alla Homepage di Apogeo Editore

Vai alla homepage di OpenPress

GTK+ / Gnome Sviluppo di Applicazioni


Il ciclo principale

Il ruolo primario del ciclo principale di GTK+ è quello di monitorare gli eventi su un descrittore connesso al server X, e inviarli ai widget. la sezione Ricevere gli eventi di GDK in GTK+ nel il capitolo I fondamenti di GDK descrive la gestione degli eventi all'interno del ciclo principale con maggiori dettagli. Questa sezione mostra il ciclo in termini generali, e descrive come aggiungere funzionalità a questo: possono essere chiamate funzioni callback quando il ciclo è in pausa, a specifici intervalli oppure quando il ciclo stesso esce.

Fondamenti per il ciclo principale

Il ciclo principale è fondamentalmente implementato in glib, che fornisce una astrazione generale un ciclo di questo genere. GTK+ collega il ciclo principale fornite da gli alla connessione di GDK al server X, e fornisce una facile interfaccia (il ciclo di glip è leggermente più a basso livello di quello fornito da GTK+). L'interfaccia del ciclo di GTK+ è descritta in Figura 28 .

gtk_main() avvia il ciclo. gtk_main() non ritornerà fino a che non verrà chiamata la funzione gtk_main_quit(). gtk_main() può essere chiamata ricorsivamente. Ciascuna chiamata a gtk_main_quit() permette la terminazione di un'unica istanza di gtk_main(). gtk_main_level() restituisce il livello di ricorsione, cioè 0 se non esiste nessuna gtk_main() all'interno dello stack, 1 se una sola gtk_main() è in esecuzione, e così via.

Tutte le istanze di gtk_main() sono funzionalmente identiche. Tutte controllano la medesima connessione al server X sulla stessa coda di eventi. Le istanze di gtk_main() vengono utilizzate per bloccare, interrompere il controllo di flusso finché non vengono soddisfatte delle condizioni. Tutti gli applicativi GTK+ utilizzano questa tecnica per evitare che la funzione main() termini durante l'esecuzione dell'applicazione. La funzione gnome_dialog_run() (maggiori informazioni nel la sezione Finestre di dialogo modali nel il capitolo Comunicare con l'utente: finestre di dialogo ) utilizza un ciclo principale ricorsivo, che non termina fino a che l'utente non preme un pulsante della finestra di dialogo.

Talvolta desiderate elaborare alcuni eventi particolari, senza però lasciare la gestione del flusso a gtk_main(). Potete eseguire una singola iterazione del ciclo principale chiamando gtk_main_iteration(). Questo può processare un singolo evento, ad esempio, dipende su quale task sono in attesa. Potete controllare se un qualunque evento è in attesa di essere processato utilizzando la funzione gtk_events_pending(). Assieme, queste due funzioni permettono di ottenere il controllo del flusso. Ad esempio, durante una lunga serie di calcoli, desiderate mostrare una barra di progressione. Dovete permettere al ciclo principale di GTK+ di essere eseguito, in modo tale che la barra di progressione possa essere ridisegnata. Utilizzate questo codice:


  while (gtk_events_pending())
    gtk_main_iteration();

#include <gtk/gtkmain.h>

void gtk_main(void);

void gtk_main_quit(void);

void gtk_main_iteration(void);

gint gtk_events_pending(void);

guint gtk_main_level(void);

Figura 28. Il ciclo principale

Funzioni di uscita

Una funzione di uscita è una callback da chiamare quando è chiamata gtk_main_quit(). In altre parole, la callback viene eseguita esattamente prima del ritorno di gtk_main(). La callback deve essere una GtkFunction, definita in questo modo:


typedef gint (*GtkFunction) (gpointer data);

Le funzioni di uscita vengono aggiunte utilizzando gtk_quit_add() ( Figura 29 ). Quando una di queste viene aggiunta, dovete specificare il livello di ciclo, restituito da gtk_main_level(). Il secondo e terzo argomento specificano una callback e i dati per questa.

Il valore restituito dalla callback indica se questa deve essere chiamata nuovamente. Finché la callback restituisce TRUE, questa chiamata verrà ripetuta. Non appena verrà restituito il valore FALSE, verrà terminata. Quando tutte le funzioni di uscita avranno restituito il valore FALSE, gtk_main() potrà uscire.

gtk_quit_add() restituisce un numero identificatore che può essere utilizzato per rimuovere una funzione di uscita attraverso gtk_quit_remove(). È possibile inoltre rimuovere una funzione di uscita passando alla callback come argomento dati la chiamata a gtk_quit_remove_by_data().

#include <gtk/gtkmain.h>

guint gtk_quit_add(guint main_level, GtkFunction function, gpointer data);

void gtk_quit_remove(guint quit_handler_id);

void gtk_quit_remove_by_data(gpointer data);

Figura 29. Funzioni di uscita

Funzioni di timeout

Le funzioni di Timeout vengono associate e dissociate esattamente come le funzioni di uscita. La callback associatavi è inoltre identica. gtk_timeout_add() aspetta come argomento un intervallo. La callback viene chiamata ogni intervallo di millisecondi. Se la callback restituisce FALSE, questa viene rimossa dalla lista delle funzioni di timeout, come se aveste chiamato gtk_timeout_remove() in una funzione di timeout. Questa modifica la lista dei timeout mentre GTK+ esegue iterazioni sopra di essa, causando un errore fatale. Dovete invece far restituire il valore FALSE per rimuovere la funzione.

#include <gtk/gtkmain.h>

guint gtk_timeout_add(guint32 interval, GtkFunction function, gpointer data);

void gtk_timeout_remove(guint timeout_handler_id);

Figura 30. Funzioni di timeout

Funzioni di pausa

Le funzioni di pausa vengono eseguite continuamente mentre il ciclo princpale di GTK+ non ne esegue nessuna. Le funzioni di pausa vengono eseguite unicamente quando la coda degli eventi è vuota e il ciclo principale è momentaneamente disoccupato, in attesa che accada qualcosa. Quando queste restituiscono un valore uguale TRUE vengono eseguite, mentre restituendo FALSE vengono rimosse. Stesso effetto del chiamare gtk_idle_remove().

La API delle funzioni di pausa, mostrata in Figura 31 , è pressochè identica a quelle delle funzioni di uscita e di timeout. Nuovamente, gtk_idel_remove() non deve essere chiamata all'interno della funzione. Restituite un valore uguale a FALSE per rimuovere la funzione.

#include <gtk/gtkmain.h>

guint gtk_idle_add(GtkFunction function, gpointer data);

void gtk_idle_remove(guint idle_handler_id);

void gtk_idle_remove_by_data(gpointer data);

Figura 31. Funzioni di pausa

Funzioni di input

Le funzioni di input vengono gestite a livello di GDK. Queste vengono invocate quando un determinato descrittore di file è pronto per la lettura o scrittura. Sono particolarmente utili per le applicazioni di rete.

Per aggiungere una funzione di input è necessario specificare il descrittore del file da monitorare, lo stato che attendete (pronto per leggere o scrivere) e una coppia callback/dati. Figura 32 mostra la API. Le funzioni possono essere rimosse utilizzando il tag restituito dalla funzione gdk_input_add(). Diversamente dalle funzioni di pausa, uscita o timeout, è sicuro chiamare gdk_input_remove() all'interno della funzione di input.

Per specificare la condizione da attendere, utilizzare i flag del GdkInputCondition: GDK_INPUT_READ, GDK_INPUT_WRITE, e GDK_INPUT_EXCEPTION. Questi corrispondono ai tre descrittori di file passati alla chiamata di sistema select(). Consultate un buon manuale di programmazione UNIX per maggiori dettagli. Se una qualunque condizione è soddisfatta, la funzione di input viene chiamata.

La callback dovrebbe appartenere a questa tipologia:


typedef void (*GdkInputFunction) (gpointer data,
                                  gint source_fd,
                                  GdkInputCondition condition);

Questa riceve i vosti dati per la callback, il descrittore del file monitorato e le condizioni soddisfatte.

#include <gdk/gdk.h>

gint gdk_input_add(gint source_fd, GdkInputCondition condition, GdkInputFunction function, gpointer data);

void gdk_input_remove(gint tag);

Figura 32. Funzioni di input


Copyright © 1995-1999 Apogeo srl, Milano