Napojení obsluhy signálu
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.
Zde je příklad napojení obsluhy signálu na signál:
#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)); }
V tomto (nefunkčním) kódu je toho hodně k zamyšlení. Nejdříve pojďme pojmenovat zúčastněné věci:
- Obsluha signálu je on_button_clicked().
- Zaháčkovali jsme ji k objektu Gtk::Button nazvanému button.
- Když Button vyšle svůj signál clicked, zavolá se on_button_clicked().
Nyní se pojďme znovu podívat na přípojení:
... button.signal_clicked().connect(sigc::ptr_fun(&on_button_clicked)); ...
Všimněte si, že ukazatel na on_button_clicked() nepředáváme přímo do metody connect() patřící signálu. Místo toho zavoláme sigc::ptr_fun() a do connect() předáme výsledek.
sigc::ptr_fun() generuje sigc::slot. Slot je objekt, který vypadá a působí jako funkce. Někdy se můžete setkat i s označením funkční objekt nebo functor. sigc::ptr_fun() generuje slot pro samostatnou funkci nebo statickou metodu. sigc::mem_fun() generuje slot pro členskou metodu konkrétní instance.
Zde je trochu rozsáhlejší příklad slotů v činnosti:
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) ); }
První volání connect() je stejné, jak jsme již viděli minule, nic nového.
Další už je podstatně zajímavější. sigc::mem_fun() je volaná se dvěma argumenty. První argument je some_object, což je objekt, na který náš nový slot bude ukazovat. Druhý argument je ukazatel na jednu z jeho metod. Tato konkrétní verze sigc::mem_fun() vytváří slot, který bude, když je „zavolán“, volat metodu určeného objektu, na kterou ukazuje, v tomto případě some_object.on_button_clicked().
Další věcí, která stojí v tomto příkladu za zmínku, je, že voláme connect() dvakrát pro ten samý objekt signálu. To je úplně v pořádku – když je na tlačítko kliknuto, jsou zavolány obě obsluhy signálu.
Právě jsme vám řekli, že signál clicked tlačítka očekává volání metody bez argumentu. Všechny signály mají obdobné požadavky – nemůžete zaháčkovat funkci se dvěma argumenty na signál, který neočekává žádný (ledaže použijete adaptér, jako je sigc::bind()). Proto je důležité znát, jaký typ obsluhy signálu byste měli očekávat, že se k danému signálu napojí.