Tooltips

Tooltips are the little information windows that pop up when you leave your pointer over a widget for a few seconds. Use set_tooltip_text() to set a text string as a tooltip on any Widget. Gtk::Tooltip is used for more advanced tooltip usage, such as showing an image as well as text.

Widget Reference

Tooltip Reference

8.6.1. Example

Figure 8-9Tooltip

Source Code

File: examplewindow.h (For use with gtkmm 4)

#ifndef GTKMM_EXAMPLEWINDOW_H
#define GTKMM_EXAMPLEWINDOW_H

#include <gtkmm.h>

class ExampleWindow : public Gtk::Window
{
public:

  ExampleWindow();
  virtual ~ExampleWindow();

protected:

  //Methods:
  void prepare_textview();
  void connect_signals();

  //Signal handlers:
  void on_markup_checkbutton_toggled();
  bool on_textview_query_tooltip(int x, int y, bool keyboard_tooltip, const Glib::RefPtr<Gtk::Tooltip>& tooltip);
  bool on_button_query_tooltip(int x, int y, bool keyboard_tooltip, const Glib::RefPtr<Gtk::Tooltip>& tooltip);

  //Child widgets:
  Gtk::Box m_vbox;

  Gtk::CheckButton m_checkbutton;
  Gtk::Label m_label;

  Gtk::ScrolledWindow m_scrolled_window;
  Gtk::TextView m_text_view;
  Glib::RefPtr<Gtk::TextBuffer> m_ref_text_buffer;
  Glib::RefPtr<Gtk::TextTag> m_ref_bold_tag;

  Gtk::Button m_button;
  Gtk::Box m_button_tooltip_widget;
};

#endif // GTKMM_EXAMPLEWINDOW_H

File: main.cc (For use with gtkmm 4)

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

int main(int argc, char *argv[])
{
  auto app = Gtk::Application::create("org.gtkmm.example");

  //Shows the window and returns when it is closed.
  return app->make_window_and_run<ExampleWindow>(argc, argv);
}

File: examplewindow.cc (For use with gtkmm 4)

#include "examplewindow.h"
#include <vector>

const Glib::ustring app_title = "gtkmm tooltips example";
const Glib::ustring non_markedup_tip = "A tooltip without markup.";
const Glib::ustring markedup_tip = "<i>Markup</i> in a tooltip.";

ExampleWindow::ExampleWindow()
  :
  m_vbox(Gtk::Orientation::VERTICAL, 3),
  m_checkbutton("Click to alternate markup in tooltip"),
  m_label("A label"),
  m_button("Button with a custom tooltip widget")
{
  //Set up window and the top-level container:
  set_title(app_title);

  m_vbox.set_margin(10);
  set_child(m_vbox);

  //Check button with markup in tooltip:
  m_checkbutton.set_tooltip_text(non_markedup_tip);
  m_vbox.append(m_checkbutton);

  //Label:
  m_label.set_tooltip_text("Another tooltip");
  m_vbox.append(m_label);

  //Textview:
  prepare_textview();

  //Button:
  //When only connecting to the query-tooltip signal, and not using any
  //of set_tooltip_text() or set_tooltip_markup(), we need to explicitly
  //tell GTK that the widget has a tooltip which we'll show.
  m_button.set_has_tooltip();
  m_vbox.append(m_button);

  //Button's custom tooltip widget:
  auto label = Gtk::make_managed<Gtk::Label>("A label in a custom tooltip widget");
  m_button_tooltip_widget.append(*label);

  connect_signals();
}

ExampleWindow::~ExampleWindow()
{
}

void ExampleWindow::prepare_textview()
{
  Gtk::TextIter iter;
  std::vector<Glib::RefPtr<Gtk::TextTag>> tags;

  //Set up a scrolled window:
  m_scrolled_window.set_child(m_text_view);
  m_scrolled_window.set_policy(Gtk::PolicyType::AUTOMATIC, Gtk::PolicyType::AUTOMATIC);
  m_scrolled_window.set_expand();
  m_vbox.append(m_scrolled_window);

  //Create a text buffer with some text:
  m_ref_text_buffer = Gtk::TextBuffer::create();

  iter = m_ref_text_buffer->end();
  m_ref_text_buffer->insert(iter, "Hover over the text ");

  //Insert some text with a tag.
  //In the tooltip signal handler below, we will show a tooltip
  //when mouse pointer is above this tagged text.
  m_ref_bold_tag = m_ref_text_buffer->create_tag("bold");
  m_ref_bold_tag->set_property("weight", Pango::Weight::BOLD);

  tags.push_back(m_ref_bold_tag);

  iter = m_ref_text_buffer->end();
  m_ref_text_buffer->insert_with_tags(iter, "in bold", tags);

  iter = m_ref_text_buffer->end();
  m_ref_text_buffer->insert(iter, " to see its tooltip");

  m_text_view.set_buffer(m_ref_text_buffer);

  m_text_view.set_size_request(320, 50);

  //When only connecting to the query-tooltip signal, and not using any
  //of set_tooltip_text() or set_tooltip_markup(), we need to explicitly
  //tell GTK that the widget has a tooltip which we'll show.
  m_text_view.set_has_tooltip();
}

void ExampleWindow::connect_signals()
{
  m_checkbutton.signal_toggled().connect(
    sigc::mem_fun(*this, &ExampleWindow::on_markup_checkbutton_toggled));

  m_text_view.signal_query_tooltip().connect(
    sigc::mem_fun(*this, &ExampleWindow::on_textview_query_tooltip), true);

  m_button.signal_query_tooltip().connect(
    sigc::mem_fun(*this, &ExampleWindow::on_button_query_tooltip), true);
}

void ExampleWindow::on_markup_checkbutton_toggled()
{
  if (m_checkbutton.get_active())
  {
    m_checkbutton.set_tooltip_markup(markedup_tip);
  }
  else
  {
    m_checkbutton.set_tooltip_markup(non_markedup_tip);
  }
}

bool ExampleWindow::on_textview_query_tooltip(int x, int y, bool keyboard_tooltip, const Glib::RefPtr<Gtk::Tooltip>& tooltip)
{
  Gtk::TextIter iter;

  if (keyboard_tooltip)
  {
    int offset = m_ref_text_buffer->property_cursor_position().get_value();
    iter = m_ref_text_buffer->get_iter_at_offset(offset);
  }
  else
  {
    int mouse_x, mouse_y, trailing;
    m_text_view.window_to_buffer_coords(Gtk::TextWindowType::TEXT,
                                        x, y, mouse_x, mouse_y);
    m_text_view.get_iter_at_position(iter, trailing, mouse_x, mouse_y);
  }

  if (!iter.has_tag(m_ref_bold_tag))
    return false;

  //Show a tooltip if the cursor or mouse pointer is over the text
  //with the specific tag:
  tooltip->set_markup("<b>Information</b> attached to a text tag");
  tooltip->set_icon("dialog-information");
  return true;
}

bool ExampleWindow::on_button_query_tooltip(int, int, bool, const Glib::RefPtr<Gtk::Tooltip>& tooltip)
{
  tooltip->set_custom(m_button_tooltip_widget);
  return true;
}