[Qt] Tres sintaxis de conexión de ranuras de señal
Directorio de artículos
Para implementar el modo de observador, puede utilizar devoluciones de llamada de función, pero existen ciertas limitaciones en el registro de funciones de devolución de llamada y la seguridad no está garantizada. Entonces, hasta cierto punto, se puede decir que la ranura de la señal Qt encapsula el mecanismo de devolución de llamada.
La ranura de señal de Qt se puede conectar (conectar) y compilar, debe cumplir dos condiciones
- El número de parámetros de la señal es mayor o igual a la función de ranura
- Para la parte con el mismo número de parámetros de la ranura de señal, los tipos de parámetros deben corresponder uno a uno
Hay tres formas de crear una conexión de ranura de señal
1. Usa los controles de la interfaz ui
El primero es usar los controles en la interfaz ui, hacer clic derecho -> ir a la ranura , y se generará un código similar al siguiente nombre de función en el cpp de la interfaz correspondiente
void MainWindow::on_pushButton_clicked()
{
}
on_WidgetName_SignalName
encendido + nombre de control + nombre de señal
De esta manera, la función de ranura se genera sin verificar en tiempo de compilación y se conecta en tiempo de ejecución, y las dos funciones se conectan a través del mecanismo de reflexión del propio sistema moc (compilador de metaobjetos) de Qt .
Por lo tanto, cuando se modifica el nombre del control, indicará que la conexión falla en tiempo de ejecución.
Otra desventaja es que este método de conexión también es inconveniente de mantener, y la conexión (conectar) y la desconexión (desconectar) no están dentro del rango controlable.
2. Sintaxis de conexión de Qt4
La segunda forma, la conexión que utiliza la sintaxis Qt4, es decir, que utiliza la expansión de macros, utiliza esencialmente el mecanismo de reflexión de las cadenas, por ejemplo:
connect(sender, SIGNAL(sigfunc()), receiver, SLOT((slotfunc()));
Los cuatro parámetros de conexión son: puntero de objeto emisor, SIGNAL (función de señal de emisor), puntero de objeto de receptor, SLOT (función de ranura de receptor)
Si observa SIGNAL
la SLOT
implementación de estas dos macros, puede notar que estas dos macros convierten el nombre de la función en una cadena
#ifndef QT_NO_META_MACROS
#ifndef QT_NO_DEBUG
#define QLOCATION "\0" __FILE__ ":" QT_STRINGIFY(__LINE__)
#ifndef QT_NO_KEYWORDS
# define METHOD(0) qFlagLocation("0"#a QLOCATION)
#endif
# define SLOT(a) qFlagLocation("1"#a QLOCATION)
# define SIGNAL(a) qFlagLocation("2"#a QLOCATION)
#else
# ifndef QT_NO_KEYWORDS
# define METHOD(a) "0"#a
# endif
# define SLOT(a) "1"#a
# define SIGNAL(a) "2"#a
#endif
#
El número se usa para encadenar los parámetros de macro detrás de él, es decir, después de reemplazar la variable después de él, se agrega una doble referencia a la izquierda y a la derecha.
La función de ranura de ranura comienza con "1", y la función de señal de señal comienza con "2". QT_STRINGIFY
La definición de una macro también es el uso de un solo signo de libra
#define QT_STRINGIFY2(x) #x
#define QT_STRINGIFY(x) QT_STRINGIFY2(x)
Sin embargo, en comparación con el primer método, este método realiza una verificación de coherencia de parámetros en forma de cadena durante la fase de compilación.
La desventaja es que es imposible confirmar si esta función está incluida en la clase. Puede poner dos funciones cuyos parámetros coincidan pero no existan en absoluto en las dos macros. También puede pasar la verificación de compilación durante la compilación, pero solicita que la conexión falla en tiempo de ejecución.
3. Sintaxis de conexión de Qt5
El tercero, la sintaxis de conexión en forma de puntero de función se proporciona en Qt5, ejemplo:
connect(sender, &Sender::signal, receiver, &Receiver::slot);
Agregar el nombre de clase a la función para tomar la dirección asegura que el compilador verifique si la señal coincide con la función de ranura, lo que puede reducir la falla de conexión en tiempo de ejecución.
También hay una variante de expresión lambda, que también usa punteros de función para conectar
connect(sender, &Sender::signal, [](){
//... implement of slot
});
Sin embargo, si la función de señal o ranura está sobrecargada en la sintaxis Qt5, o ambas están sobrecargadas, la conexión no se emparejará de forma inteligente y se usará directamente en caso de sobrecarga, y la compilación informará un error. es como sigue:
no matching member function for call to 'connect'
No hay función de miembro coincidente para la llamada para conectarse
Puede usar QOverload de Qt para manejar, si hay las siguientes funciones de señal y ranura
signals:
void sigfunc(int);
void sigfunc(QString);
//...
public slots:
void slotfunc(int);
void slotfunc(QString);
Se puede usar cuando se conecta QOverload<T>::of
, ejemplo:
connect(sender, QOverload<int>::of(&Sender::sigfunc),
receiver, QOverload<int>::of(&Receiver::slotfunc));
y
connect(sender, QOverload<QString>::of(&Sender::sigfunc),
receiver, QOverload<QString>::of(&Receiver::slotfunc));
Sobrecargas para conectar señales y slots (int, QString)