TEORIA DEI SEGNALI

 

Abbiamo fin qui visto come si inizializza un'applicazione Gnome/Gtk+.

Una volta inizializzate le librerie avremo quindi a disposizione gli elementi per la costruzione della nostra interfaccia grafica (widget) che potremo creare ed utilizzare a piacimento con la funzione gtk_nomedelwidget_new() e con i metodi relativi ai singoli widget.

Ma come possiamo fare interagire i widget che creiamo con la nostra applicazione?
In altre parole, una volta costruita una finestra con un bottone, come possiamo fare in modo che quando l'utente lo prema venga chiamata una routine che svolga una determinata azione?

Ciò è possibile mediante i segnali e le funzioni di callback.

I widget infatti emettono dei segnali quando accade qualcosa che li riguarda ai quali l'applicazione può ripondere. Per rispondere ad un segnale basta associarvi una funzione di callback.
Ad esempio:

gint gtk_signal_connect( GtkObject *object,
gchar *name,
GtkSignalFunc func,
gpointer func_data );

Dove il primo argomento è il widget che emetterà il segnale ed il secondo il nome del segnale che vogliamo intercettare. Il terzo è la funzione che vogliamo sia chiamata quando il segnale viene emesso ed il quarto i dati che vogliamo che siano passati a questa funzione.

La funzione specificata nel terzo argomento è appunto chiamata funzione di "callback" ed avrà normalmente la forma:

void callback_func( GtkWidget *widget,
gpointer callback_data );

Dove il primo argomento è un puntatore al widget che emette il segnale, ed il secondo un puntatore ai dati che gli vengono passati dalla funzione signal_connect.

La struttura della funzione di callback illustrata è generica. Alcune widget generano chiamate differenti. E' buona norma ricordare che i file header dei widget sono la migliore guida di riferimento per le strutture delle funzioni di callback.

 

 

ELENCO SEGNALI

GtkObject

void GtkObject::destroy (GtkObject *,
gpointer);

GtkWidget

void GtkWidget::show (GtkWidget *,
gpointer);
void GtkWidget::hide (GtkWidget *,
gpointer);
void GtkWidget::map (GtkWidget *,
gpointer);
void GtkWidget::unmap (GtkWidget *,
gpointer);
void GtkWidget::realize (GtkWidget *,
gpointer);
void GtkWidget::unrealize (GtkWidget *,
gpointer);
void GtkWidget::draw (GtkWidget *,
ggpointer,
gpointer);
void GtkWidget::draw-focus (GtkWidget *,
gpointer);
void GtkWidget::draw-default (GtkWidget *,
gpointer);
void GtkWidget::size-request (GtkWidget *,
ggpointer,
gpointer);
void GtkWidget::size-allocate (GtkWidget *,
ggpointer,
gpointer);
void GtkWidget::state-changed (GtkWidget *,
GtkStateType,
gpointer);
void GtkWidget::parent-set (GtkWidget *,
GtkObject *,
gpointer);
void GtkWidget::style-set (GtkWidget *,
GtkStyle *,
gpointer);
void GtkWidget::add-accelerator (GtkWidget *,
gguint,
GtkAccelGroup *,
gguint,
GdkModifierType,
GtkAccelFlags,
gpointer);
void GtkWidget::remove-accelerator (GtkWidget *,
GtkAccelGroup *,
gguint,
GdkModifierType,
gpointer);
gboolean GtkWidget::event (GtkWidget *,
GdkEvent *,
gpointer);
gboolean GtkWidget::button-press-event (GtkWidget *,
GdkEvent *,
gpointer);
gboolean GtkWidget::button-release-event (GtkWidget *,
GdkEvent *,
gpointer);
gboolean GtkWidget::motion-notify-event (GtkWidget *,
GdkEvent *,
gpointer);
gboolean GtkWidget::delete-event (GtkWidget *,
GdkEvent *,
gpointer);
gboolean GtkWidget::destroy-event (GtkWidget *,
GdkEvent *,
gpointer);
gboolean GtkWidget::expose-event (GtkWidget *,
GdkEvent *,
gpointer);
gboolean GtkWidget::key-press-event (GtkWidget *,
GdkEvent *,
gpointer);
gboolean GtkWidget::key-release-event (GtkWidget *,
GdkEvent *,
gpointer);
gboolean GtkWidget::enter-notify-event (GtkWidget *,
GdkEvent *,
gpointer);
gboolean GtkWidget::leave-notify-event (GtkWidget *,
GdkEvent *,
gpointer);
gboolean GtkWidget::configure-event (GtkWidget *,
GdkEvent *,
gpointer);
gboolean GtkWidget::focus-in-event (GtkWidget *,
GdkEvent *,
gpointer);
gboolean GtkWidget::focus-out-event (GtkWidget *,
GdkEvent *,
gpointer);
gboolean GtkWidget::map-event (GtkWidget *,
GdkEvent *,
gpointer);
gboolean GtkWidget::unmap-event (GtkWidget *,
GdkEvent *,
gpointer);
gboolean GtkWidget::property-notify-event (GtkWidget *,
GdkEvent *,
gpointer);
gboolean GtkWidget::selection-clear-event (GtkWidget *,
GdkEvent *,
gpointer);
gboolean GtkWidget::selection-request-event (GtkWidget *,
GdkEvent *,
gpointer);
gboolean GtkWidget::selection-notify-event (GtkWidget *,
GdkEvent *,
gpointer);
void GtkWidget::selection-get (GtkWidget *,
GtkSelectionData *,
gguint,
gpointer);
void GtkWidget::selection-received (GtkWidget *,
GtkSelectionData *,
gguint,
gpointer);
gboolean GtkWidget::proximity-in-event (GtkWidget *,
GdkEvent *,
gpointer);
gboolean GtkWidget::proximity-out-event (GtkWidget *,
GdkEvent *,
gpointer);
void GtkWidget::drag-begin (GtkWidget *,
GdkDragContext *,
gpointer);
void GtkWidget::drag-end (GtkWidget *,
GdkDragContext *,
gpointer);
void GtkWidget::drag-data-delete (GtkWidget *,
GdkDragContext *,
gpointer);
void GtkWidget::drag-leave (GtkWidget *,
GdkDragContext *,
gguint,
gpointer);
gboolean GtkWidget::drag-motion (GtkWidget *,
GdkDragContext *,
ggint,
ggint,
gguint,
gpointer);
gboolean GtkWidget::drag-drop (GtkWidget *,
GdkDragContext *,
ggint,
ggint,
gguint,
gpointer);
void GtkWidget::drag-data-get (GtkWidget *,
GdkDragContext *,
GtkSelectionData *,
gguint,
gguint,
gpointer);
void GtkWidget::drag-data-received (GtkWidget *,
GdkDragContext *,
ggint,
ggint,
GtkSelectionData *,
gguint,
gguint,
gpointer);
gboolean GtkWidget::client-event (GtkWidget *,
GdkEvent *,
gpointer);
gboolean GtkWidget::no-expose-event (GtkWidget *,
GdkEvent *,
gpointer);
gboolean GtkWidget::visibility-notify-event (GtkWidget *,
GdkEvent *,
gpointer);
void GtkWidget::debug-msg (GtkWidget *,
GtkString *,
gpointer);

GtkData

void GtkData::disconnect (GtkData *,
gpointer);

GtkContainer

void GtkContainer::add (GtkContainer *,
GtkWidget *,
gpointer);
void GtkContainer::remove (GtkContainer *,
GtkWidget *,
gpointer);
void GtkContainer::check-resize (GtkContainer *,
gpointer);
GtkDirectionType GtkContainer::focus (GtkContainer *,
GtkDirectionType,
gpointer);
void GtkContainer::set-focus-child (GtkContainer *,
GtkWidget *,
gpointer);

GtkCalendar

void GtkCalendar::month-changed (GtkCalendar *,
gpointer);
void GtkCalendar::day-selected (GtkCalendar *,
gpointer);
void GtkCalendar::day-selected-double-click (GtkCalendar *,
gpointer);
void GtkCalendar::prev-month (GtkCalendar *,
gpointer);
void GtkCalendar::next-month (GtkCalendar *,
gpointer);
void GtkCalendar::prev-year (GtkCalendar *,
gpointer);
void GtkCalendar::next-year (GtkCalendar *,
gpointer);

GtkEditable

void GtkEditable::changed (GtkEditable *,
gpointer);
void GtkEditable::insert-text (GtkEditable *,
GtkString *,
ggint,
ggpointer,
gpointer);
void GtkEditable::delete-text (GtkEditable *,
ggint,
ggint,
gpointer);
void GtkEditable::activate (GtkEditable *,
gpointer);
void GtkEditable::set-editable (GtkEditable *,
gboolean,
gpointer);
void GtkEditable::move-cursor (GtkEditable *,
ggint,
ggint,
gpointer);
void GtkEditable::move-word (GtkEditable *,
ggint,
gpointer);
void GtkEditable::move-page (GtkEditable *,
ggint,
ggint,
gpointer);
void GtkEditable::move-to-row (GtkEditable *,
ggint,
gpointer);
void GtkEditable::move-to-column (GtkEditable *,
ggint,
gpointer);
void GtkEditable::kill-char (GtkEditable *,
ggint,
gpointer);
void GtkEditable::kill-word (GtkEditable *,
ggint,
gpointer);
void GtkEditable::kill-line (GtkEditable *,
ggint,
gpointer);
void GtkEditable::cut-clipboard (GtkEditable *,
gpointer);
void GtkEditable::copy-clipboard (GtkEditable *,
gpointer);
void GtkEditable::paste-clipboard (GtkEditable *,
gpointer);

GtkTipsQuery

void GtkTipsQuery::start-query (GtkTipsQuery *,
gpointer);
void GtkTipsQuery::stop-query (GtkTipsQuery *,
gpointer);
void GtkTipsQuery::widget-entered (GtkTipsQuery *,
GtkWidget *,
GtkString *,
GtkString *,
gpointer);
gboolean GtkTipsQuery::widget-selected (GtkTipsQuery *,
GtkWidget *,
GtkString *,
GtkString *,
GdkEvent *,
gpointer);

GtkCList

void GtkCList::select-row (GtkCList *,
ggint,
ggint,
GdkEvent *,
gpointer);
void GtkCList::unselect-row (GtkCList *,
ggint,
ggint,
GdkEvent *,
gpointer);
void GtkCList::row-move (GtkCList *,
ggint,
ggint,
gpointer);
void GtkCList::click-column (GtkCList *,
ggint,
gpointer);
void GtkCList::resize-column (GtkCList *,
ggint,
ggint,
gpointer);
void GtkCList::toggle-focus-row (GtkCList *,
gpointer);
void GtkCList::select-all (GtkCList *,
gpointer);
void GtkCList::unselect-all (GtkCList *,
gpointer);
void GtkCList::undo-selection (GtkCList *,
gpointer);
void GtkCList::start-selection (GtkCList *,
gpointer);
void GtkCList::end-selection (GtkCList *,
gpointer);
void GtkCList::toggle-add-mode (GtkCList *,
gpointer);
void GtkCList::extend-selection (GtkCList *,
GtkScrollType,
ggfloat,
gboolean,
gpointer);
void GtkCList::scroll-vertical (GtkCList *,
GtkScrollType,
ggfloat,
gpointer);
void GtkCList::scroll-horizontal (GtkCList *,
GtkScrollType,
ggfloat,
gpointer);
void GtkCList::abort-column-resize (GtkCList *,
gpointer);

GtkNotebook

void GtkNotebook::switch-page (GtkNotebook *,
ggpointer,
gguint,
gpointer);

GtkList

void GtkList::selection-changed (GtkList *,
gpointer);
void GtkList::select-child (GtkList *,
GtkWidget *,
gpointer);
void GtkList::unselect-child (GtkList *,
GtkWidget *,
gpointer);

GtkMenuShell

void GtkMenuShell::deactivate (GtkMenuShell *,
gpointer);
void GtkMenuShell::selection-done (GtkMenuShell *,
gpointer);
void GtkMenuShell::move-current (GtkMenuShell *,
GtkMenuDirectionType,
gpointer);
void GtkMenuShell::activate-current (GtkMenuShell *,
gboolean,
gpointer);
void GtkMenuShell::cancel (GtkMenuShell *,
gpointer);

GtkToolbar

void GtkToolbar::orientation-changed (GtkToolbar *,
ggint,
gpointer);
void GtkToolbar::style-changed (GtkToolbar *,
ggint,
gpointer);

GtkTree

void GtkTree::selection-changed (GtkTree *,
gpointer);
void GtkTree::select-child (GtkTree *,
GtkWidget *,
gpointer);
void GtkTree::unselect-child (GtkTree *,
GtkWidget *,
gpointer);

GtkButton

void GtkButton::pressed (GtkButton *,
gpointer);
void GtkButton::released (GtkButton *,
gpointer);
void GtkButton::clicked (GtkButton *,
gpointer);
void GtkButton::enter (GtkButton *,
gpointer);
void GtkButton::leave (GtkButton *,
gpointer);

GtkItem

void GtkItem::select (GtkItem *,
gpointer);
void GtkItem::deselect (GtkItem *,
gpointer);
void GtkItem::toggle (GtkItem *,
gpointer);

GtkWindow

void GtkWindow::set-focus (GtkWindow *,
ggpointer,
gpointer);

GtkHandleBox

void GtkHandleBox::child-attached (GtkHandleBox *,
GtkWidget *,
gpointer);
void GtkHandleBox::child-detached (GtkHandleBox *,
GtkWidget *,
gpointer);

GtkToggleButton

void GtkToggleButton::toggled (GtkToggleButton *,
gpointer);

GtkMenuItem

void GtkMenuItem::activate (GtkMenuItem *,
gpointer);
void GtkMenuItem::activate-item (GtkMenuItem *,
gpointer);

GtkListItem

void GtkListItem::toggle-focus-row (GtkListItem *,
gpointer);
void GtkListItem::select-all (GtkListItem *,
gpointer);
void GtkListItem::unselect-all (GtkListItem *,
gpointer);
void GtkListItem::undo-selection (GtkListItem *,
gpointer);
void GtkListItem::start-selection (GtkListItem *,
gpointer);
void GtkListItem::end-selection (GtkListItem *,
gpointer);
void GtkListItem::toggle-add-mode (GtkListItem *,
gpointer);
void GtkListItem::extend-selection (GtkListItem *,
GtkEnum,
ggfloat,
gboolean,
gpointer);
void GtkListItem::scroll-vertical (GtkListItem *,
GtkEnum,
ggfloat,
gpointer);
void GtkListItem::scroll-horizontal (GtkListItem *,
GtkEnum,
ggfloat,
gpointer);

GtkTreeItem

void GtkTreeItem::collapse (GtkTreeItem *,
gpointer);
void GtkTreeItem::expand (GtkTreeItem *,
gpointer);

GtkCheckMenuItem

void GtkCheckMenuItem::toggled (GtkCheckMenuItem *,
gpointer);

GtkColorSelection

void GtkColorSelection::color-changed (GtkColorSelection *,
gpointer);

GtkStatusBar

void GtkStatusbar::text-pushed (GtkStatusbar *,
gguint,
GtkString *,
gpointer);
void GtkStatusbar::text-popped (GtkStatusbar *,
gguint,
GtkString *,
gpointer);

GtkCTree

void GtkCTree::tree-select-row (GtkCTree *,
GtkCTreeNode *,
ggint,
gpointer);
void GtkCTree::tree-unselect-row (GtkCTree *,
GtkCTreeNode *,
ggint,
gpointer);
void GtkCTree::tree-expand (GtkCTree *,
GtkCTreeNode *,
gpointer);
void GtkCTree::tree-collapse (GtkCTree *,
ggpointer,
gpointer);
void GtkCTree::tree-move (GtkCTree *,
GtkCTreeNode *,
GtkCTreeNode *,
GtkCTreeNode *,
gpointer);
void GtkCTree::change-focus-row-expansion (GtkCTree *,
GtkCTreeExpansionType,
gpointer);

GtkCurve

void GtkCurve::curve-type-changed (GtkCurve *,
gpointer);

GtkAdjustment

void GtkAdjustment::changed (GtkAdjustment *,
gpointer);
void GtkAdjustment::value-changed (GtkAdjustment *,
gpointer);


Il ciclo principale.

Una volta creati e posizionati i widget dobbiamo entrare nel ciclo principale di Gtk+ che ha appunto la funzione di monitorare gli eventi connessi al server X in modo da poter inviare i segnali ai widget.
Il ciclo principale viene avviato con gtk_main() che non ritornerà fino a quando non verrà chiamata la funzione gtk_main_quit().

gtk_main() può essere chiamata ricorsivamente. Tutte le istanze di gtk_main() sono funzionalmente identiche e vengono utilizzate per interrompere il controllo di flusso fino a che non vengono soddisfatte delle condizioni. gtk_main_level() restituisce il livello di ricorsione.

Talvolta si può volere che siano elaborati alcuni eventi particolari, senza però lasciare la gestione del flusso a gtk_main(). Si può eseguire una singola iterazione del ciclo principale chiamando gtk_main_iteration() che può processare un singolo evento. Inoltre si può controllare se un qualunque evento è in attesa di essere processato attraverso la funzione gtk_events_pending().
Queste due funzioni usate insieme permettono di ottenere il controllo del flusso.

Ad esempio se si vuole forzare il refresh (ridisegno) dei widget (si pensi ad una barra di progressione) si può utilizzare il codice:

while (gtk_events_pending())
gtk_main_iteration();

 

Torna all'indice