Overriding default signal handlers

So far we've told you to perform actions in response to button-presses and the like by handling signals. That's certainly a good way to do things, but it's not the only way.

Instead of laboriously connecting signal handlers to signals, you can simply make a new class which inherits from a widget - say, a Button - and then override the default signal handler, such as Button::on_clicked(). This can be a lot simpler than hooking up signal handlers for everything.

Subclassing isn't always the best way to accomplish things. It is only useful when you want the widget to handle its own signal by itself. If you want some other class to handle the signal then you'll need to connect a separate handler. This is even more true if you want several objects to handle the same signal, or if you want one signal handler to respond to the same signal from different objects.

gtkmm classes are designed with overriding in mind; they contain virtual member methods specifically intended to be overridden.

Let's look at an example of overriding:

#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();
}

Here we define a new class called OverriddenButton, which inherits from Gtk::Button. The only thing we change is the on_clicked() method, which is called whenever Gtk::Button emits the clicked signal. This method prints "Hello World" to stdout, and then calls the original, overridden method, to let Gtk::Button do what it would have done had we not overridden.

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.