Home > Gtk3, PyGObject, python > PyGObject: Signals

PyGObject: Signals

13 Aprile 2020

torna all’indice appunti

Main loop e Signals

GTK+ utilizza un modello di programmazione event-driven, ovvero GTK+ attende nel mainloop che un
utente esegua un’azione. Quando questo avviene, ad esempio un click su un pulsante,
il mainloop se ne accorge e spedisce l’evento corrispondente a GTK+.
Quando un widget (es. Button) riceve un evento (es. viene premuto), emette uno o più segnali.
Questi segnali notificano al programma che sta accadendo qualcosa di interessante ed invocano le
funzioni (callbacks) che ad essi sono collegate.
Quando la callback ha terminato il suo compito, GTK+ ritorna nel mainloop attendendo una nuova
azione da parte dell’utente.

Il metodo che lega un widget ad un evento è connect(event, callback, *data):

handler_id = widget.connect("event", callback, data)

widget: è un’istanza di un widget creata in precedenza;

Parametri:
event: è l’evento al quale siamo interessati. In genere ogni
widget ha un evento particolare, ad esempio Button sarà interessato all’evento “clicked”.
callback: il nome della funzione di callback che verrà invocata
quando quel determinato evento accadrà;
data: opzionale ed indica i valori da passare alla callback;

Il metodo connect(), ritorna il numero identificativo dell’handler che gestisce
la coppia signal-callback.

>>> import gi
>>> gi.require_version("Gtk", "3.0")
>>> from gi.repository import Gtk
>>> button = Gtk.Button(label="Ok")
>>> button.connect("clicked", lambda widget: print("clicked"))
23
>>> button.clicked()
clicked

Qualora dovessimo disconnettere il widget da quel segnale, è possibile utilizzare il metodo
disconnect(handler_id):

>>> button.disconnect(23)
>>> button.clicked()

>>>

E’ possibile anche disconnettere un widget da un evento, via funzione, con il metodo
disconnect_by_func(callback):

>>> def on_click(button):
...     print("clicked")    
...     
>>> button.connect("clicked", on_click)
24
>>> button.clicked()
clicked
>>> button.disconnect_by_func(on_click)
1
>>> button.clicked()

>>>

Gtk.main_quit()

Connettere l’applicazione al segnale “destroy” della top-level window.
Quando l’utente chiude la toplevel window, l’handler di default per questo segnale distrugge
la window, ma non termina l’applicazione.
Connettendo il segnale “destroy” della top-level window alla Gtk.main_quit() darà invece il
risultato desiderato.

window.connect("destroy", Gtk.main_quit)

La chiamata a Gtk.main_quit() fa ritornare il main loop precedentemente creato
con Gtk.main().

Objects

GObject è il “tipo” fondamentale che fornisce gli attributi e i metodi per tutti
i tipi di oggetto di GTK+, Pango e le altre librerie basate su GObject.
La classe GObject.GObject fornisce i metodi per la costruzione e la distruzione
degli oggetti, i metodi per l’accesso alle properties degli oggetti, il supporto ai segnali.

Signals

I Signals connettono eventi arbitrari ai “listeners” di competenza.
Per esempio in GTK+, ogni evento (pressione di un tasto o movimento del mouse), viene ricevuto dal
server X che genera un evento GTK+ sotto forma di emissione di segnale.
Ogni segnale viene registrato nel type system insieme al type, sul quale può eseere emesso.
Per quel type, verrà registrata una funzione che sarà invocata ogni volta che sarà emesso quel
segnale specifico. Un segnale può essere emesso anche volontariamente o si può decidere di fermare
l’emissione del segnale dall’interno di una delle funzioni connesse a quel segnale.

Creare un nuovo segnale

Possiamo creare nuovi segnali aggiungendoli al dizionario GObject.GObject.__gsignals__:
Quando un nuovo segnale viene creato, può essere definito anche un method-handler, che sarà
invocato ogni volta che il segnale verrà emesso.

class CustomObject(GObject.GObject):
    __gsignals__ = {'custom_signal': (GObject.SIGNAL_RUN_FIRST, None, (int,)),}

    def emit_signal(self, arg):
        print("method handler for 'custom_signal' called with argument", arg)

Parametri:
GObject.SIGNAL_RUN_FIRST: indica che questo segnale invocherà
il method handler definito (emit_signal()) nella fase di prima emissione.
Le alternative sono:
GObject.SIGNAL_RUN_LAST: il method handler sarà invocato nella terza fase di emissione;
GObject.SIGNAL_RUN_CLEANUP: invoca il method handler nell’ultima fase di emissione.
None: indica cosa ritorna il segnale, di solito None.
(int,): indica gli argomenti del segnale.
Nel nostro caso il segnale prende un solo argomento di tipo int.

I segnali possono essere emessi con il metodo GObject.GObject.emit():

>>> from gi.repository import GObject
>>> class CustomObject(GObject.GObject):
...     __gsignals__ = {'custom_signal': (GObject.SIGNAL_RUN_FIRST, None, (int,)),}
... 
...     def do_custom_signal(self, arg):
...         print("method handler for 'custom_signal' called with argument", arg)
...         
>>> obj = CustomObject()
>>> obj.emit("custom_signal", 23)
method handler for 'custom_signal' called with argument 23

link di riferimento:
torna all’indice degli appunti
python gtk3 tutorial
Gtk3

Categorie:Gtk3, PyGObject, python Tag: , ,
I commenti sono chiusi.