Conectar gestores de señales
gtkmm widget classes have signal accessor methods, such as Gtk::Button::signal_clicked(), which allow you to connect your signal handler. Thanks to the flexibility of libsigc++, the callback library used by gtkmm, the signal handler can be almost any kind of function, but you will probably want to use a class method. Among GTK C coders, these signal handlers are often named callbacks.
Aquí hay un ejemplo de un gestor de señales que se conecta a una señal:
#include <gtkmm/button.h> void on_button_clicked() { std::cout << "Hello World" << std::endl; } int main() { Gtk::Button button("Hello World"); button.signal_clicked().connect(sigc::ptr_fun(&on_button_clicked)); }
Hay mucho para pensar en este código no funcional. Primero, identifique a los grupos involucrados:
- El gestor de señales es on_button_clicked().
- Se engancha al objeto Gtk::Button llamado button.
- Cuando el botón emita su señal clicked, se llamará a on_button_clicked().
Ahora, mire la conexión nuevamente:
... button.signal_clicked().connect(sigc::ptr_fun(&on_button_clicked)); ...
Tenga en cuenta que no se le pasa un puntero a on_button_clicked() directamente al método de la señal connect(). En su lugar, se llama a sigc::ptr_fun(), y se le pasa el resultado a connect().
sigc::ptr_fun() genera un sigc::slot. Un «slot» es un objeto que se comporta como una función, pero en realidad es un objeto. Estos también se llaman objetos función, o funtores. sigc::ptr_fun() genera un «slot» para una función independiente o un método estático. sigc::mem_fun() genera un «slot» para un método miembro de una instancia particular.
Aquí hay un ejemplo ligeramente más amplio de los «slots» en acción:
void on_button_clicked(); class some_class { void on_button_clicked(); }; some_class some_object; int main() { Gtk::Button button; button.signal_clicked().connect( sigc::ptr_fun(&on_button_clicked) ); button.signal_clicked().connect( sigc::mem_fun(some_object, &some_class::on_button_clicked) ); }
La primera llamada a connect() es igual a la que vio la última vez; no hay nada nuevo aquí.
La siguiente es más interesante. sigc::mem_fun() se llama con dos argumentos. El primero es some_object, que es el objeto al que su nuevo «slot» apuntará. El segundo argumento es un puntero a uno de sus métodos. Esta versión particular de sigc::mem_fun() crea un «slot» que, cuando se «llame», llamará al método al que apunta del objeto especificado, en este caso, some_object.on_button_clicked().
Otra cosa notable acerca de este ejemplo es que se ha hecho la llamada a connect() dos veces para el mismo objeto de señal. Esto está perfectamente bien: cuando se pulse el botón, se llamará a ambos gestores de señales.
Como se mencionó, la señal clicked del botón está esperando llamar a un método sin argumentos. Todas las señales tienen requerimientos como este: no puede enganchar una función con dos argumentos a una señal que no espera ninguno (a menos que use un adaptador, como sigc::bind(), por supuesto). Por lo tanto, es importante saber qué tipo de gestor de señales se esperará que conecte a una señal dada.