Dialogs in wxWidgets

Dialog windows or dialogs are an indispensable part of most modern GUI applications. A dialog is defined as a conversation between two or more persons. In a computer application a dialog is a window which is used to "talk" to the application. A dialog is used to input data, modify data, change the application settings etc. Dialogs are important means of communication between a user and a computer program.

There are essentially two types of dialogs: predefined dialogs and custom dialogs.

Predefined dialogs

Predefined dialogs are dialogs available in the wxWidgets toolkit. These are dialogs for common programming tasks like showing text, receiving input, loading and saving files etc. They save programmer's time and enhance using some standard behaviour.

Message dialogs

Message dialogs are used to show messages to the user. They are customisable. We can change icons and buttons that will be shown in a dialog.

Messages.h
#include <wx/wx.h>

class Messages : public wxFrame
{
public:
    Messages(const wxString& title);
    
    void ShowMessage1(wxCommandEvent & event);
    void ShowMessage2(wxCommandEvent & event);
    void ShowMessage3(wxCommandEvent & event);
    void ShowMessage4(wxCommandEvent & event);

};

const int ID_INFO = 1;
const int ID_ERROR = 2;
const int ID_QUESTION = 3;
const int ID_ALERT = 4;
Messages.cpp
#include "Messages.h"

Messages::Messages(const wxString& title)
       : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(210, 110))
{

  wxPanel *panel = new wxPanel(this, wxID_ANY);

  wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL);
  wxGridSizer *gs = new wxGridSizer(2, 2, 2, 2);

  wxButton *btn1 = new wxButton(panel, ID_INFO, wxT("Info"));
  wxButton *btn2 = new wxButton(panel, ID_ERROR, wxT("Error"));
  wxButton *btn3 = new wxButton(panel, ID_QUESTION, wxT("Question"));
  wxButton *btn4 = new wxButton(panel, ID_ALERT, wxT("Alert"));

  Connect(ID_INFO, wxEVT_COMMAND_BUTTON_CLICKED, 
      wxCommandEventHandler(Messages::ShowMessage1));
  Connect(ID_ERROR, wxEVT_COMMAND_BUTTON_CLICKED, 
      wxCommandEventHandler(Messages::ShowMessage2));
  Connect(ID_QUESTION, wxEVT_COMMAND_BUTTON_CLICKED, 
      wxCommandEventHandler(Messages::ShowMessage3));
  Connect(ID_ALERT, wxEVT_COMMAND_BUTTON_CLICKED, 
      wxCommandEventHandler(Messages::ShowMessage4));

  gs->Add(btn1, 1, wxEXPAND);
  gs->Add(btn2, 1);
  gs->Add(btn3, 1);
  gs->Add(btn4, 1);

  hbox->Add(gs, 0, wxALL, 15);
  panel->SetSizer(hbox);

  Center();
}


void Messages::ShowMessage1(wxCommandEvent& event) 
{
  wxMessageDialog *dial = new wxMessageDialog(NULL, 
      wxT("Download completed"), wxT("Info"), wxOK);
  dial->ShowModal();
}

void Messages::ShowMessage2(wxCommandEvent& event) 
{
   wxMessageDialog *dial = new wxMessageDialog(NULL, 
      wxT("Error loading file"), wxT("Error"), wxOK | wxICON_ERROR);
   dial->ShowModal();
}

void Messages::ShowMessage3(wxCommandEvent& event) 
{
  wxMessageDialog *dial = new wxMessageDialog(NULL, 
      wxT("Are you sure to quit?"), wxT("Question"), 
      wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION);
  dial->ShowModal();
}

void Messages::ShowMessage4(wxCommandEvent& event) 
{
  wxMessageDialog *dial = new wxMessageDialog(NULL, 
      wxT("Unallowed operation"), wxT("Exclamation"), 
      wxOK | wxICON_EXCLAMATION);
  dial->ShowModal();
}
main.h
#include <wx/wx.h>

class MyApp : public wxApp
{
  public:
    virtual bool OnInit();
};
main.cpp
#include "main.h"
#include "Messages.h"

IMPLEMENT_APP(MyApp)

bool MyApp::OnInit()
{

  Messages *msgs = new Messages(wxT("Messages"));
  msgs->Show(true);

  return true;
}

In our example, we have created four buttons and put them in a grid sizer. These buttons will show four different dialog windows. We create them by specifying different style flags.

wxMessageDialog *dial = new wxMessageDialog(NULL, 
   wxT("Error loading file"), wxT("Error"), wxOK | wxICON_ERROR);
dial->ShowModal();

The creation of the message dialog is simple. We set the dialog to be a toplevel window by providing NULL as a parent. The two strings provide the message text and the dialog title. We show an OK button and an error icon by specifying the wxOK and wxICON_ERROR flags. To show the dialog on screen, we call the ShowModal() method.

Info dialog Question dialog Alert dialog Error dialog

wxFileDialog

This is a common dialog for opening and saving files.

openfile.h
#include <wx/wx.h>

class Openfile : public wxFrame
{
public:
  Openfile(const wxString& title);

  void OnOpen(wxCommandEvent& event);

  wxTextCtrl *tc;

};
openfile.cpp
#include "openfile.h"

Openfile::Openfile(const wxString & title)
       : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(300, 200))
{

  wxMenuBar *menubar = new wxMenuBar;
  wxMenu *file = new wxMenu;
  file->Append(wxID_OPEN, wxT("&Open"));
  menubar->Append(file, wxT("&File"));
  SetMenuBar(menubar);

  Connect(wxID_OPEN, wxEVT_COMMAND_MENU_SELECTED, 
      wxCommandEventHandler(Openfile::OnOpen));


  tc = new wxTextCtrl(this, -1, wxT(""), wxPoint(-1, -1), 
      wxSize(-1, -1), wxTE_MULTILINE);

  Center();

}

void Openfile::OnOpen(wxCommandEvent& event)
{

  wxFileDialog * openFileDialog = new wxFileDialog(this);

  if (openFileDialog->ShowModal() == wxID_OK){
      wxString fileName = openFileDialog->GetPath();
      tc->LoadFile(fileName);     
  }
}
main.h
#include <wx/wx.h>

class MyApp : public wxApp
{
  public:
    virtual bool OnInit();
};
main.cpp
#include "main.h"
#include "openfile.h"

IMPLEMENT_APP(MyApp)

bool MyApp::OnInit()
{

    Openfile *open = new Openfile(wxT("Openfile"));
    open->Show(true);

    return true;
}

In our example, we display a open file menu item and a simple multiline text control. If we click on the open file menu item a wxFileDialog is displayed. We can load some simple text files into the text control.

tc = new wxTextCtrl(this, -1, wxT(""), wxPoint(-1, -1), 
    wxSize(-1, -1), wxTE_MULTILINE);

We load text files into this text control.

wxFileDialog * openFileDialog = new wxFileDialog(this);

Here we create a wxFileDialog. We use the default parameters. (The open file dialog is the default dialog.)

if (openFileDialog->ShowModal() == wxID_OK){
    wxString fileName = openFileDialog->GetPath();
    tc->LoadFile(fileName);     
}

Here we show the dialog. We get the selected file name and load the file into the text control.

wxFileDialog
Figure: wxFileDialog on Linux

wxFontDialog

This is a common dialog for choosing a font.

fontdialog.h
#include <wx/wx.h>

class ChangeFont : public wxFrame
{
public:
  ChangeFont(const wxString& title);

  void OnOpen(wxCommandEvent& event);

  wxStaticText *st;

};

const int ID_FONTDIALOG = 1;
fontdialog.cpp
#include <wx/fontdlg.h>
#include "fontdialog.h"

ChangeFont::ChangeFont(const wxString & title)
       : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(300, 200))
{

  wxPanel *panel = new wxPanel(this, -1);

  wxMenuBar *menubar = new wxMenuBar;
  wxMenu *file = new wxMenu;
  file->Append(ID_FONTDIALOG, wxT("&Change font"));
  menubar->Append(file, wxT("&File"));
  SetMenuBar(menubar);

  Connect(ID_FONTDIALOG, wxEVT_COMMAND_MENU_SELECTED, 
      wxCommandEventHandler(ChangeFont::OnOpen));

  st = new wxStaticText(panel, wxID_ANY, wxT("The Agoge"), 
      wxPoint(20, 20));

  Center();

}


void ChangeFont::OnOpen(wxCommandEvent& WXUNUSED(event))
{
  wxFontDialog *fontDialog = new wxFontDialog(this);

  if (fontDialog->ShowModal() == wxID_OK) {
    st->SetFont(fontDialog->GetFontData().GetChosenFont());
  }

}
main.h
#include <wx/wx.h>

class MyApp : public wxApp
{
  public:
    virtual bool OnInit();
};
main.cpp
#include "main.h"
#include "fontdialog.h"

IMPLEMENT_APP(MyApp)

bool MyApp::OnInit()
{

    ChangeFont *change = new ChangeFont(wxT("Change font"));
    change->Show(true);

    return true;
}

In this example, we will change the font of a static text example.

st = new wxStaticText(panel, wxID_ANY, wxT("The Agoge"), 
    wxPoint(20, 20));

Here we display a static text on the panel. We will change its font using the wxFontDialog.

wxFontDialog *fontDialog = new wxFontDialog(this);

if (fontDialog->ShowModal() == wxID_OK) {
  st->SetFont(fontDialog->GetFontData().GetChosenFont());
}

In these code lines, we show the font dialog. Then we get the choosen font. And finally, we change the font of the static text, we created earlier.

Font dialog
Figure: Font dialog

A custom dialog

In the next example we create a custom dialog. An image editing application can change a color depth of a picture. To provide this funcionality, we could create a suitable custom dialog.

customdialog.h
#include <wx/wx.h>

class CustomDialog : public wxDialog
{
public:
  CustomDialog(const wxString& title);

};
customdialog.cpp
#include "customdialog.h"

CustomDialog::CustomDialog(const wxString & title)
       : wxDialog(NULL, -1, title, wxDefaultPosition, wxSize(250, 230))
{

  wxPanel *panel = new wxPanel(this, -1);

  wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
  wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL);

  wxStaticBox *st = new wxStaticBox(panel, -1, wxT("Colors"), 
      wxPoint(5, 5), wxSize(240, 150));
  wxRadioButton *rb = new wxRadioButton(panel, -1, 
      wxT("256 Colors"), wxPoint(15, 30), wxDefaultSize, wxRB_GROUP);

  wxRadioButton *rb1 = new wxRadioButton(panel, -1, 
      wxT("16 Colors"), wxPoint(15, 55));
  wxRadioButton *rb2 = new wxRadioButton(panel, -1, 
      wxT("2 Colors"), wxPoint(15, 80));
  wxRadioButton *rb3 = new wxRadioButton(panel, -1, 
      wxT("Custom"), wxPoint(15, 105));
  wxTextCtrl *tc = new wxTextCtrl(panel, -1, wxT(""), 
      wxPoint(95, 105));

  wxButton *okButton = new wxButton(this, -1, wxT("Ok"), 
      wxDefaultPosition, wxSize(70, 30));
  wxButton *closeButton = new wxButton(this, -1, wxT("Close"), 
      wxDefaultPosition, wxSize(70, 30));

  hbox->Add(okButton, 1);
  hbox->Add(closeButton, 1, wxLEFT, 5);

  vbox->Add(panel, 1);
  vbox->Add(hbox, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, 10);

  SetSizer(vbox);

  Centre();
  ShowModal();

  Destroy(); 
}
main.h
#include <wx/wx.h>

class MyApp : public wxApp
{
  public:
    virtual bool OnInit();
};
main.cpp
#include "main.h"
#include "customdialog.h"

IMPLEMENT_APP(MyApp)

bool MyApp::OnInit()
{

    CustomDialog *custom = new CustomDialog(wxT("CustomDialog"));
    custom->Show(true);

    return true;
}

This example is a dialog based application. We illustrate, how to create a custom dialog.

class CustomDialog : public wxDialog

A custom dialog is based on the wxDialog class.

wxStaticBox *st = new wxStaticBox(panel, -1, wxT("Colors"), 
    wxPoint(5, 5), wxSize(240, 150));
wxRadioButton *rb = new wxRadioButton(panel, -1, 
    wxT("256 Colors"), wxPoint(15, 30), wxDefaultSize, wxRB_GROUP);

Note that wxStaticBox widget must be created before the widgets that it contains, and that those widgets should be siblings, not children, of the static box.

ShowModal();
Destroy();

To show the dialog on the screen, we call the ShowModal() method. To clear the dialog from the memory, we call the Destroy() method.

Custom dialog
Figure: Custom dialog

This part of the wxWidgets tutorial was dedicated to dialogs.