Chapter 17. Dialogs

Table of Contents

[Note] Note

Gtk::Dialog and the classes derived from it, are deprecated since gtkmm 4.10. They can still be used in gtkmm4 applications, provided GTKMM_DISABLE_DEPRECATED and GDKMM_DISABLE_DEPRECATED are not defined. Some of the dialog classes are replaced by classes that are available since gtkmm 4.10.

The examples in this chapter use classes that are available since gtkmm 4.10. Similar examples with the deprecated classes are available in the gtkmm-4-0 branch in the git repository.

Dialogs are used as secondary windows, to provide specific information or to ask questions. Gtk::Dialog windows contain a few pre-packed widgets to ensure consistency, and a response signal which is emitted when the user dismisses the dialog.

There are several derived Dialog classes which you might find useful. Gtk::MessageDialog is used for most simple notifications. But at other times you might need to derive your own dialog class to provide more complex functionality.

To pack widgets into a custom dialog, you should pack them into the Gtk::Box, available via get_content_area(). To just add a Button to the bottom of the Dialog, you could use the add_button() method.

The response signal handler receives an int. This may be a value from the Gtk::ResponseType if the user closed the dialog by clicking a standard button, or it could be the custom response value that you specified when using add_button().

To show the dialog, call set_visible(true). If the same dialog instance will be shown several times, you must also call set_hide_on_close(), or else the dialog will be destroyed when it's closed. Connect to the response signal, if you want to know which button was pressed. The response signal handler is also where you should hide the dialog.

Reference

AlertDialog and MessageDialog

MessageDialog (deprecated since gtkmm 4.10) and AlertDialog (available since gtkmm 4.10) are convenience classes, used to create simple, standard message dialogs, with a message and buttons for user response.

AlertDialog Reference

MessageDialog Reference

Example

Figure 17.1. AlertDialog

AlertDialog

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();
  ~ExampleWindow() override;

protected:
  //Signal handlers:
  void on_button_info_clicked();
  void on_button_question_clicked();
  void on_question_dialog_finish(const Glib::RefPtr<Gio::AsyncResult>& result);

  //Child widgets:
  Gtk::Box m_ButtonBox;
  Gtk::Button m_Button_Info;
  Gtk::Button m_Button_Question;

  Glib::RefPtr<Gtk::AlertDialog> m_pDialog;
};

#endif //GTKMM_EXAMPLEWINDOW_H

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

#include "examplewindow.h"
#include <gtkmm/messagedialog.h>
#include <iostream>


ExampleWindow::ExampleWindow()
: m_ButtonBox(Gtk::Orientation::VERTICAL),
  m_Button_Info("Show Info AlertDialog"),
  m_Button_Question("Show Question AlertDialog")
{
  set_title("Gtk::AlertDialog example");

  set_child(m_ButtonBox);

  m_ButtonBox.append(m_Button_Info);
  m_Button_Info.set_expand(true);
  m_Button_Info.signal_clicked().connect(sigc::mem_fun(*this,
              &ExampleWindow::on_button_info_clicked) );

  m_ButtonBox.append(m_Button_Question);
  m_Button_Question.set_expand(true);
  m_Button_Question.signal_clicked().connect(sigc::mem_fun(*this,
              &ExampleWindow::on_button_question_clicked) );
}

ExampleWindow::~ExampleWindow()
{
}

void ExampleWindow::on_button_info_clicked()
{
  if (!m_pDialog)
    m_pDialog = Gtk::AlertDialog::create();
  else
  {
    // Reset values that may have been set by on_button_question_clicked().
    m_pDialog->set_buttons({});
    m_pDialog->set_default_button(-1);
    m_pDialog->set_cancel_button(-1);
  }

  m_pDialog->set_message("This is an INFO AlertDialog.");
  m_pDialog->set_detail("And this is the secondary text that explains things.");
  m_pDialog->show(*this);
}

void ExampleWindow::on_button_question_clicked()
{
  if (!m_pDialog)
    m_pDialog = Gtk::AlertDialog::create();
  m_pDialog->set_message("This is a QUESTION AlertDialog.");
  m_pDialog->set_detail("And this is the secondary text that explains things.");
  m_pDialog->set_buttons({"Cancel", "Retry", "OK"});
  m_pDialog->set_default_button(2); // OK button or Return key
  m_pDialog->set_cancel_button(0); // Cancel button or Escape key
  m_pDialog->choose(*this,
    sigc::mem_fun(*this, &ExampleWindow::on_question_dialog_finish));
}

void ExampleWindow::on_question_dialog_finish(const Glib::RefPtr<Gio::AsyncResult>& result)
{
  try
  {
    const int response_id = m_pDialog->choose_finish(result);
    switch (response_id)
    {
    case 0:
      std::cout << "Cancel clicked." << std::endl;
      break;
    case 1:
      std::cout << "Retry clicked." << std::endl;
      break;
    case 2:
      std::cout << "OK clicked." << std::endl;
      break;
    default:
      std::cout << "Unexpected response: " << response_id << std::endl;
      break;
    }
  }
  catch (const Gtk::DialogError& err)
  {
    // Can be thrown by m_pDialog->choose_finish(result).
    std::cout << "DialogError, " << err.what() << std::endl;
  }
  catch (const Glib::Error& err)
  {
    std::cout << "Unexpected exception. " << err.what() << std::endl;
  }
}

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