Chapter 13. Widgets Without X-Windows

Table of Contents

Some Widgets do not have an associated X-Window, so they therefore do not receive X events. This means that the signals described in the X event signals section will not be emitted. If you want to capture events for these widgets you can use a special container called Gtk::EventBox, which is described in the EventBox section.

Here is a list of some of these Widgets:

Gtk::Alignment
Gtk::Arrow
Gtk::Bin
Gtk::Box
Gtk::Button
Gtk::CheckButton
Gtk::Fixed
Gtk::Image
Gtk::Item
Gtk::Label
Gtk::MenuItem
Gtk::Notebook
Gtk::Paned
Gtk::Pixmap
Gtk::RadioButton
Gtk::Range
Gtk::ScrolledWindow
Gtk::Separator
Gtk::Table
Gtk::Toolbar
Gtk::AspectFrame
Gtk::Frame
Gtk::VBox
Gtk::HBox
Gtk::VSeparator
Gtk::HSeparator

These widgets are mainly used for decoration or layout, so you won't often need to capture events on them. They are intended to have no X-Window in order to improve performance.

EventBox

Some gtkmm widgets don't have associated X windows; they draw on their parents' windows. Because of this, they cannot receive events. Also, if they are incorrectly sized, they don't clip, so you can get messy overwriting etc. To receive events on one of these widgets, you can it inside an EventBox widget and then call Gtk::Widget::set_events() on the EventBox before showing it.

Although the name EventBox emphasises the event-handling method, the widget can also be used for clipping (and more; see the example below).

TODO: Why don't they have X Windows - explain clipping. Also, how does this affect platform such as Windows and MacOS that don't use X.

The constructor for Gtk::EventBox is:

Gtk::EventBox();

A child widget can be added to the EventBox using:

event_box.add(child_widget);

Reference

Example

The following example demonstrates both uses of an EventBox - a label is created that is clipped to a small box, and set up so that a mouse-click on the label causes the program to exit. Resizing the window reveals varying amounts of the label.

Figure 13.1. EventBox

EventBox

Source Code

File: examplewindow.h

#ifndef GTKMM_EXAMPLEWINDOW_H
#define GTKMM_EXAMPLEWINDOW_H

#include <gtkmm.h>

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

protected:
  //Signal handlers:
  virtual bool on_eventbox_button_press(GdkEventButton* event);

  //Child widgets:
  Gtk::EventBox m_EventBox;
  Gtk::Label m_Label;
};

#endif //GTKMM_EXAMPLEWINDOW_H

File: main.cc

#include <gtkmm/main.h>
#include "examplewindow.h"

int main(int argc, char *argv[])
{
  Gtk::Main kit(argc, argv);

  ExampleWindow window;
  //Shows the window and returns when it is closed.
  Gtk::Main::run(window);

  return 0;
}

File: examplewindow.cc

#include "examplewindow.h"

ExampleWindow::ExampleWindow()
: m_Label("Click here to quit, quit, quit, quit, quit")
{
  set_title ("EventBox");
  set_border_width(10);

  add(m_EventBox);

  m_EventBox.add(m_Label);

  //Clip the label short:
  m_Label.set_size_request(110, 20);

  //And bind an action to it:
  m_EventBox.set_events(Gdk::BUTTON_PRESS_MASK);
  m_EventBox.signal_button_press_event().connect(
    sigc::mem_fun(*this, &ExampleWindow::on_eventbox_button_press) );

  m_EventBox.set_tooltip_text("Click me!");

  show_all_children();
}

ExampleWindow::~ExampleWindow()
{
}

bool ExampleWindow::on_eventbox_button_press(GdkEventButton*)
{
  hide();
  return true;
}