Intro
El framework para GUIs Qt dispone de un mecanismo de intercomunicación entre objetos llamado Signals & Slots.
Esto es especialmente útil para notificar cambios en widgets a otros widgets o procesos.
Una Signal (señal) es emitida cuando ocurre un evento en particular. Los widgets
(subclases de QObject) tienen muchas señales predefinidas para notificar sobre
sus propios eventos y nosotros podemos crear nuevas señales también en esos
widgets o en nuestro propio código.
Un Slot (ranura) es una función que es llamada en respuesta a la emisión de una señal determinada.
Uso
Para conectar Signals y Slots, usamos la función connect de Qt:
connect(Objeto1, signal, Objeto2, slot);
En versiones anteriores a Qt5, había que especificar SIGNAL y SLOT:
connect(Objeto1, SIGNAL(signal), Objeto2, SLOT(slot);
Ejemplos
Acción tras la Signal predeterminada de un QObject
Supongamos que queremos realizar alguna acción cuando el usuario inserte texto
en un QLineEdit.
Este evento de un usuario escribiendo en un widget QLineEdit emite siempre una
Signal textChanged.
Sabiendo esto, podemos añadir un método a nuestra clase para que actúe en base a
la emisión de dicha Signal. Suponiendo que el QLineEdit que queremos conectar
es myLineEdit:
|
|
…y ahora conectaremos esa Signal (ese evento) del QLineEdit en nuestro
Slot:
|
|
Delegación en QMetaObject::classInfoOffset
La clase QMetaObject contiene
metainformación sobre objetos Qt. En concreto, uno de sus miembros públicos es
connectSlotsByName,
que busca Signals recursivamente en todos los objetos descendientes del actual,
conectándolas con Slots que sigan la siguiente nomenclatura:
void on_<object name>_<signal name>(<signal parameters>);
Por ejemplo, si hubiéramos nombrado a nuestro Slot:
private slots:
void on_myLineEdit_textChanged();
No hubiera hecho falta escribir la función connect en nuestro constructor.
Escribir nuestra propia Signal para notificar un evento
Del mismo modo que hemos definido nuestro Slot para gestionar la emisión de una Signal por un tercer objeto, podemos crear nuestra propia Signal para que notifique acerca de un evento en nuestro código a otros objetos que la esperen.
Para ello hemos de definir la Signal en la clase de nuestro objeto:
|
|
Ahora podemos usar esta Signal de este modo:
|
|