Přepisování výchozí obsluhy signálu

Doposud jste se dozvěděli, jak provést nějakou činnost na základě zmáčknutí tlačítka a jak obsluhovat signály. To je samozřejmě dobrý způsob, jak dělat věci, ale není jediný.

Namísto pracného napojení obsluhy signálu na signál můžete jednoduše vytvořit novou třídu, která bude zděděná z widgetu – řekněme tlačítka – a přepsat jeho výchozí obsluhu signálu, jako je Button::on_clicked(). To může být mnohem jednodušší, než se zaháčkovat na obsluhu signálu pro všechno.

Tvorba podtříd není ale vždy nejlepším způsobem, jak dosáhnout kýženého. Je použitelná jen, když widget obsluhuje své vlastní signály. Když chcete, aby signál obsluhovala jiná třída, potřebujete napojit samostatnou obsluhu. Platí to o to víc, když chcete aby stejný signál obsluhovalo několik objektů, nebo chcete, aby jedna obsluha reagovala na stejný signál z více různých objektů.

Třídy gtkmm jsou navržené přímo s ohledem na přepisování. Obsahují virtuální členské metody speciálně zamýšlené za účelem přepsání.

Pojďme se podívat na příklad s přepsáním:

#include <gtkmm/button.h>

class OverriddenButton : public Gtk::Button
{
protected:
  void on_clicked() override;
}

void OverriddenButton::on_clicked()
{
  std::cout << "Hello World" << std::endl;

  // call the base class's version of the method:
  Gtk::Button::on_clicked();
}

Zde definujeme novou třídu nazvanou OverriddenButton, která je zděděná z Gtk::Button. Jedinou věcí, kterou měníme, je metoda on_clicked(), která je zavolaná, kdykoliv Gtk::Button vyšle signál clicked. Tato metoda vypíše „Hello World“ na stdout a pak zavolá původní, přepsanou metodu, aby třída Gtk::Button mohla udělat to, co by dělala, kdybychom ji nepřepsali.

You don't always need to call the parent's method; there are times when you might not want to. Note that we called the parent method after writing "Hello World", but we could have called it before. In this simple example, it hardly matters much, but there are times when it will. With connected signal handlers, it's not quite so easy to change details like this, and you can do something here which you can't do at all with connected signal handlers: you can call the parent method in the middle of your custom code.