[Qt] Tres sintaxis de conexión de ranuras de señal

[Qt] Tres sintaxis de conexión de ranuras de señal

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

  1. El número de parámetros de la señal es mayor o igual a la función de ranura
  2. 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 SIGNALla SLOTimplementació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_STRINGIFYLa 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)

Supongo que te gusta

Origin blog.csdn.net/weixin_44488341/article/details/132235578
Recomendado
Clasificación