Anuncios

Bienvenidos sean a este post, hoy verermos al encargado de la magia de los elementos.

Anuncios
Anuncios

Qt introduce el concepto de señales y slots como un mecanismo flexible de comunicaciones entre los objetos. En este post hablamos sobre el patron observador y es muy similar a este mecanismo, en el patron tenemos suscriptores y estos son notificados cuando sucede un evento. Qt provee una interfaz generica que se puede usar para conectar objetos entre si mediante la señal de uno al slot de otro. Ambos son funciones miembros comunes de objetos, siendo la señal una funcion que es invocada en una accion especifica para el objeto y el slot es otra funcion que actua como suscriptor porque es invocada por la señal.

Anuncios

En el post anterior, vimos un ejemplo de como manejar un evento con una clase. En ella mencionamos a al macro o tipo base que usaremos para manejar todos los objetos como es QObject. Este nos brinda la funcionalidad basica para soportar las señales y slots, esto se aplica a cualquier objeto en nuestro codigo como QWidget, QPushButton y cualquier otra inherente a QObject. Este nos provee dos funciones para gestionar las comunicaciones, estas son connect y disconnect. Veamos como son sus definiciones:

bool connect(const QObject* sender, const char* signal, const QObject* receiver, 
  const char* method, Qt::ConnectionType type = Qt::AutoConnect);

bool disconnect(const QObject* sender, const char* signal, const QObject* receiver, 
  const char* method);
Anuncios
Anuncios

En ambas funciones tenemos un objeto para el que envia (sender) y otro para el que recibe (receiver), y tambien para otros argumentos para la señal (signal) y otro para el slot (method). Pero en connect tenemos dos argumentos para definir ell tipo de conexion y en caso de no pasar uno, utilizara a AutoConnect. A medida que trabajemos con aplicaciones Qt nos familiziaremos con las señales y slots, tal como nos pasa con otros frameworks, y a su vez estan siendo usadas como cadenas. Por lo general, para establecer a las señales y slots usamos a las macros SIGNAL y SLOT respectivamente. Tomemos el primer ejemplo que vimos en el post anterior y hagamos el siguiente cambio:

#include <QtWidgets>

int main(int argc, char** argv)
{
  QApplication app(argc, argv);
  QPushButton btn("Aprietame");
  QLabel lbl;
  lbl.setText("Ninguna señal recibida");
  QObject::connect(&btn, SIGNAL(clicked()), &lbl,
        SLOT(setText(const QString&)));

  lbl.show();
  btn.show();
  return app.exec();
}
Anuncios

Es muy similar a lo visto en el post anterior, primero generamos a la aplicacion mediante QApplication y luego tenemos el boton de QPushButton. Despues tenemos la primera modificacion, en este caso agregamos una etiqueta del tipo QLabel, esta al igual que QApplication y QPushButton son parte de QtWidgets, y en este objeto aplicamos a setText para establecer un texto. Luego tenemos a la funcion connect para unir al boton y a la etiqueta. Como señal usaremos cuando se hace un click en el boton y como slot estableceremos un texto, en este caso ninguno, para finalmente mostrar ambos elementos y ejecutar a la aplicacion. Compilemos con todos los pasos necesarios y veamos como trabaja:

Anuncios

Observen como se muestran los dos elementos pero si ven la consola, nos notificara que no se puede enviar pero esto igualmente sucede porque de esta manera no tenemos la posibilidad de poder enviar un cambio a otro elemento. Para poder verlo funcionando debemos hacer el siguiente cambio:

#include <QtWidgets>

class Etiqueta : public QLabel
{
Q_OBJECT

public slots:
    void setTexto()
    {
        this->setText("Señal recibida");
    }
};

int main(int argc, char** argv)
{
  QApplication app(argc, argv);

  QPushButton btn("Aprrietame");
  Etiqueta lbl;

  lbl.setText("Ninguna señal recibida");
  QObject::connect(&btn, SIGNAL(clicked()), &lbl,SLOT(setTexto()));

  lbl.show();
  btn.show();

  return app.exec();
}

#include "qt.moc"
Anuncios
Anuncios

La primera modificacion es el agregado de la clase Etiqueta. Esta sera heredera de QLabel, dentro tenemos a la macro Q_OBJECT para poder acceder a todos los objetos. En esta clase, no tenemos ni un public ni un private sino a public slots. Esto es para identificar no solo que son slots sino que tambien son publicos y pueden ser usados por cualquiera. Aqui definimos un metodo llamado setMetodo donde usara al puntero para ejecutar al metodo setText de QLabel y establecer un texto. Luego en el main, realizamos muy pocas modificaciones. La primera es que nuestra etiqueta no es mas de QLabel sino de la nueva clase. La siguiente modificacion es en connect donde ahora pasaremos al metodo de la nueva clase para el slot. Y la ultima modificacion es incluir al archivo .moc, y este debe llevar el nombre del archivo del codigo fuente. En mi caso es este pero ajustenlo al de ustedes, por ejemplo si el archivo se llama pepito.cpp deben usar pepito.moc. Esto lo debemos agregar principalmente para que se genere correctamente el entorno en memoria, asi como tambien nos permite tener un mejor control para el metacompilador. Ahora tenemos un metodo personalizado para nuestro slot, compilemos y veamos como trabaja ahora:

Anuncios

Como pueden ver, ahora si la presion del boton nos permite modificar el contenido de la etiqueta. Esto gracias a la señal y el slot. Como pueden ver, esto es muy parecido a lo que podemos hacer en framework orientados a entornos web o visual basic. Donde al accionarse el evento, toma accion y realiza la accion correspondiente.

Anuncios

Si observan en la clase tenemos un nuevo tipo de acceso llamado public slots, y como mencionamos anterirorrmente, nos sirve para establecer a que slots podemos acceder por fuera de la clase mediante una instancia. Sin embargo tenemos mas disponible, veamos cuales son:

  • public slots: slots para acceder desde la instancia u objeto
  • private slots: slots que solo pertenecen a la clase
  • signals: aqui establecemos los prototipos de las funciones a utilizar y no es publico, privado o protegida
Anuncios

Tambien disponemos de public y protect para los metodos y clases propias de la clase. Sobre estos tipos de acceso en la clase hablaremos un poco mas adelante en otro post. Y para ir finalizando, volvamos a la funcion connect donde dijimos que existe un quinto argumento para determinar como es el tipo de conexion, si no lo informamos este tomara el valor predeterminado de AutoConnect pero disponemos de los siguientes valores:

  • DirectConnection: se invoca al slot cuando la señal es emitida
  • QueuedConnection:: este invoca al slot solo cuando la señal vuelve del thread del receptor
  • AutoConnection: puede ser cualquiera de los dos anteriores (valor predeterminado)
  • BlockingQueuedConnection: bloquea la conexion que espera hasta que se complete la tarea del slot (no recomendado)
  • UniqueConnection: en union con las tres primeras establece que esa conexion sera la unica y anula cualquiera que sea similar
Anuncios

En resumen, hoy hemos visto a señales y slots, que son, para que sirven, como se utilizan, una serie de ejemplos para ver como trabajan y algunas caracteristicas mas. Espero les haya resultado de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios
pp258

Donación

Es para mantenimento del sitio, gracias!

$1.50