gtkmm/button.h

Wuttup toons!

Buttons are used everywhere so it's a good idea to master them. The Gtk::Button class is a beast and there are several button types that subclass and specialize this monster.

Button types

Buttons are created by specifying a label in their constructors. You can also associate a mnemonic hotkey to it. To do this, place an underscore before the letter that you want as the mnemonic and pass in true as the second argument of the constructor.

auto button = new Gtk::Button("Device _Manager", true);  

Note that button will always be a pointer to a Gtk::Button. Also note that all buttons are Gtk::Container's, which means you can put anything other widgets inside a button, including images.

That said, in the project below, I will demonstrate how to use a set_label to decorate a member button with a label object.

A window with a button

Create a project folder with two inner folders called src and include. In src add a main.cpp file that looks like this:

#include "buttonWindow.h"
#include <gtkmm/application.h>

int main(int argc, char** argv) {  
  auto app = Gtk::Application::
    create(
      argc, argv,
      "org.animatedlew.buttons"
    );
  ButtonWindow window;
  return app->run(window);
}

This is all standard stuff. Every Gtk app needs to have a Gtk::Application object. In this example, we create a ButtonWindow instance and feed it into app's event loop: app->run(buttons).

Next, we'll need to subclass Gtk::Window so we can encapsulate the button construction.

#pragma once

#include <gtkmm/window.h>
#include <gtkmm/button.h>

class ButtonWindow : public Gtk::Window {  
public:  
  ButtonWindow();
  virtual ~ButtonWindow();

protected:  
  void onClicked();
  Gtk::Button button;
};

Now that we have that header blocked out, let's add our final source file. In src, add buttonWindow.cpp and describe it like this:

#include "buttonWindow.h"
#include <iostream>

ButtonWindow::ButtonWindow() {

  // style the window a bit...
  set_title("Button Window");
  set_border_width(10);

  // hook up the onClicked handler to the signal
  button
    .signal_clicked()
    .connect(sigc::mem_fun(*this,
      &ButtonWindow::onClicked));

  // give the button a label
  button.set_label("Call for help!");

  // add the button to the window container
  add(button);

  // saves us from calling show on all widgets
  show_all_children();
}

ButtonWindow::~ButtonWindow() {}

void ButtonWindow::onClicked() {  
  std::cout << "S.O.S.!!!" << std::endl;
}

The first thing we do in our window's constructor, is style the borders and set a title. The next thing we do is hook up the clicked signal and add a label to the button. The actual definition of our onClicked signal handler simply responds with a console message. I think it needs help...

Final thoughts

It's a good idea to get comfortable hooking up signals since it's at the core of this event driven system. Buttons have a on_clicked signal that can be overwritten, but I don't find that too useful. I prefer a run-time hookup over inheritance any day. In our case, we allow the window container handle these events.

In the next session, we'll discuss the Gtk::ToggleButton. You can think of this one as a switch since it remembers its last state. In the meantime, I encourage you to make a utility with the stuff you have learned.

...and remember to stay wise!