wxAuiNotebook

Introduction

The wxAuiNotebook (wxWidgets: wxAuiNotebook Class Reference) widget is a version of the wxNotebook widget that provides additional ways to display the pages. For a presentation of the capabilities of the wxNotebook widget you can read our wxNotebook tutorial.

The video below shows how the user can organize the pages of a wxAuiNotebook widget.

First Example

Below we show a simple example of a wxAuiNotebook with two tabs. As shown in the introduction the tabs can be moved around the window. The example is a simple modification of the MinimalApp2 example we presented in the minimal application tutorial. The full source for this example is available from our GitHub repository: wxWidgetsTutorials/wxAUI/WxAuiNotebook1.

 File: wxAUI/WxAuiNotebook1/src/WxAuiNotebook1Frame.cpp
#include "WxAuiNotebook1Frame.h"
#include <wx/aui/aui.h>
#include <wx/textctrl.h>

WxAuiNotebook1Frame::WxAuiNotebook1Frame(const wxString& title)
    : wxFrame(NULL, wxID_ANY, title)
{
    // Create a top-level panel to hold all the contents of the frame
    wxPanel* panel = new wxPanel(this, wxID_ANY);

    // Create the wxAuiNotebook widget
    wxAuiNotebook* auiNotebook = new wxAuiNotebook(panel, wxID_ANY);

    // Add 2 pages to the wxNotebook widget
    wxTextCtrl* textCtrl1 = new wxTextCtrl(auiNotebook, wxID_ANY, L"Tab 1 Contents");
    auiNotebook->AddPage(textCtrl1, L"Tab 1");
    wxTextCtrl* textCtrl2 = new wxTextCtrl(auiNotebook, wxID_ANY, L"Tab 2 Contents");
    auiNotebook->AddPage(textCtrl2, L"Tab 2");

    // Set up the sizer for the panel
    wxBoxSizer* panelSizer = new wxBoxSizer(wxHORIZONTAL);
    panelSizer->Add(auiNotebook, 1, wxEXPAND);
    panel->SetSizer(panelSizer);

    // Set up the sizer for the frame and resize the frame
    // according to its contents
    wxBoxSizer* topSizer = new wxBoxSizer(wxHORIZONTAL);
    topSizer->SetMinSize(250, 200);
    topSizer->Add(panel, 1, wxEXPAND);
    SetSizerAndFit(topSizer);
}

The application is shown in Figure 1 below.

Figure 1: The WxAuiNotebook1 Application

The rest of the files don't have any significant changes but are shown here for completeness.

 File: wxAUI/WxAuiNotebook1/src/WxAuiNotebook1Frame.h
#ifndef _TUTORIALS_WXWIDGETS_WXAUI_WXAUINOTEBOOK1FRAME_H_
#define _TUTORIALS_WXWIDGETS_WXAUI_WXAUINOTEBOOK1FRAME_H_

#include <wx/frame.h>

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

#endif
 File: wxAUI/WxAuiNotebook1/src/WxAuiNotebook1App.h
#ifndef _TUTORIALS_WXWIDGETS_WXAUI_WXAUINOTEBOOK1APP_H_
#define _TUTORIALS_WXWIDGETS_WXAUI_WXAUINOTEBOOK1APP_H_

#include <wx/app.h>

class WxAuiNotebook1App : public wxApp
{
public:
    virtual bool OnInit();
};

#endif
 File: wxAUI/WxAuiNotebook1/src/WxAuiNotebook1App.cpp
#include "WxAuiNotebook1App.h"
#include "WxAuiNotebook1Frame.h"

wxIMPLEMENT_APP(WxAuiNotebook1App);

bool WxAuiNotebook1App::OnInit()
{
    WxAuiNotebook1Frame* frame = new WxAuiNotebook1Frame("WxAuiNotebook1");
    frame->Show(true);
    return true;
}

Page Change Events

We will now show how to make use of the events generated when a user changes the selected page. Two events are relevant:

  • The EVT_AUINOTEBOOK_PAGE_CHANGING event is generated when the page selection change is initiated but the selected page hasn't changed yet.
  • The EVT_AUINOTEBOOK_PAGE_CHANGED event is generated after the selected page has been changed.

A simple example showing handlers for these events is presented below. The events are used to update the contents of a wxTextCtrl control. The full source for this example is available from our GitHub repository: wxWidgetsTutorials/wxAUI/WxAuiNotebook2.

The following changes were made to the previous example:

  • A wxTextCtrl control has been added to the main window to display some information that changes when some events happen.
  • The OnPageChanging handler was added to handle EVT_AUINOTEBOOK_PAGE_CHANGING events. It keeps track of how many times it was called in the m_pageChangingCount variable. The count will be displayed in the wxTextCtrl control.
  • The OnPageChanged handler was added to handle EVT_AUINOTEBOOK_PAGE_CHANGED events. It updates the contents of the wxTextCtrl control.
  • Some minor changes to improve the layout: the size of the wxAuiNotebook control is fixed in the sizer and the minimum size of the main window sizer has been increased to 400.

The changes are highlighted in the source files shown below.

 File: wxAUI/WxAuiNotebook2/src/WxAuiNotebook2Frame.h
#ifndef _TUTORIALS_WXWIDGETS_WXAUI_WXAUINOTEBOOK2FRAME_H_
#define _TUTORIALS_WXWIDGETS_WXAUI_WXAUINOTEBOOK2FRAME_H_

#include <wx/frame.h>
#include <wx/textctrl.h>
#include <wx/aui/aui.h>

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

private:
    wxTextCtrl* m_mainContents;
    unsigned int m_pageChangingCount;

private:
    void OnPageChanging(wxAuiNotebookEvent& evt);
    void OnPageChanged(wxAuiNotebookEvent& evt);

    wxDECLARE_EVENT_TABLE();
};

#endif
 File: wxAUI/WxAuiNotebook2/src/WxAuiNotebook2Frame.cpp
#include "WxAuiNotebook2Frame.h"
#include "WindowIDs.h"
#include <wx/textctrl.h>
#include <sstream>

WxAuiNotebook2Frame::WxAuiNotebook2Frame(const wxString& title)
    : wxFrame(NULL, wxID_ANY, title), m_mainContents(0), m_pageChangingCount(0)
{
    // Create a top-level panel to hold all the contents of the frame
    wxPanel* panel = new wxPanel(this, wxID_ANY);

    // Create the wxAuiNotebook widget
    wxAuiNotebook* auiNotebook = new wxAuiNotebook(panel, NotebookID,
        wxDefaultPosition, wxSize(150, 200));

    // Add 2 pages to the wxNotebook widget
    wxTextCtrl* textCtrl1 = new wxTextCtrl(auiNotebook, wxID_ANY, L"Tab 1 Contents");
    auiNotebook->AddPage(textCtrl1, L"Tab 1");
    wxTextCtrl* textCtrl2 = new wxTextCtrl(auiNotebook, wxID_ANY, L"Tab 2 Contents");
    auiNotebook->AddPage(textCtrl2, L"Tab 2");

    // Create the right-hand side panel, it's simply a textbox
    m_mainContents = new wxTextCtrl(panel, wxID_ANY, L"Main Contents Area");

    // Set up the sizer for the panel
    wxBoxSizer* panelSizer = new wxBoxSizer(wxHORIZONTAL);
    panelSizer->Add(auiNotebook, 0, wxEXPAND);
    panelSizer->Add(m_mainContents, 1, wxEXPAND);
    panel->SetSizer(panelSizer);

    // Set up the sizer for the frame and resize the frame
    // according to its contents
    wxBoxSizer* topSizer = new wxBoxSizer(wxHORIZONTAL);
    topSizer->SetMinSize(400, 200);
    topSizer->Add(panel, 1, wxEXPAND);
    SetSizerAndFit(topSizer);
}

// Called when the selected page in the wxNotebook is going to be
// changed. We simply keep a count that we display on the right-hand
// side to show that the function is being called.
// In practice you may not need to write a handler for this event at
// all.
void WxAuiNotebook2Frame::OnPageChanging(wxAuiNotebookEvent& evt)
{
    ++m_pageChangingCount;
    evt.Skip();
}

// Called when the selected page in the wxNotebook has been changed.
// In our example we update the contents of the righ-hand side textbox.
void WxAuiNotebook2Frame::OnPageChanged(wxAuiNotebookEvent& evt)
{
    std::wstringstream contents;
    switch (evt.GetSelection())
    {
    case 0:
        contents << L"Tab 1 selected, page changed ";
        break;

    case 1:
        contents << L"Tab 2 selected, page changed ";
        break;
    }
    contents << m_pageChangingCount << " times";
    if (m_mainContents)
    {
        m_mainContents->SetValue(contents.str());
    }
    evt.Skip();
}

// Add the 2 event handlers to the event table. As you can see we use
// the window ID to link the event handlers to the wxAuiNotebook we created.
wxBEGIN_EVENT_TABLE(WxAuiNotebook2Frame, wxFrame)
    EVT_AUINOTEBOOK_PAGE_CHANGING(NotebookID, WxAuiNotebook2Frame::OnPageChanging)
    EVT_AUINOTEBOOK_PAGE_CHANGED(NotebookID, WxAuiNotebook2Frame::OnPageChanged)
wxEND_EVENT_TABLE()

The behaviour of the WxAuiNotebook2 application is shown in the 2 figures below. Note that the difference in appearance between these screenshots and Figure 1 is because they were taken on different versions of Windows.

Figure 2: The WxNotebook2 application at startup

Figure 3: The WxNotebook2 application after tab 2 has been selected

The rest of the source files don't contain significant changes but are shown here for completeness.

 File: wxAUI/WxAuiNotebook2/src/WindowIDs.h
#ifndef _TUTORIALS_WXWIDGETS_WXAUI_WINDOWIDS_H_
#define _TUTORIALS_WXWIDGETS_WXAUI_WINDOWIDS_H_

#include <wx/defs.h>

const wxWindowID NotebookID = wxID_HIGHEST + 1;

#endif
 File: wxAUI/WxAuiNotebook2/src/WxAuiNotebook2App.h
#ifndef _TUTORIALS_WXWIDGETS_WXAUI_WXAUINOTEBOOK2APP_H_
#define _TUTORIALS_WXWIDGETS_WXAUI_WXAUINOTEBOOK2APP_H_

#include <wx/app.h>

class WxAuiNotebook2App : public wxApp
{
public:
    virtual bool OnInit();
};

#endif
 File: wxAUI/WxAuiNotebook2/src/WxAuiNotebook2App.cpp
#include "WxAuiNotebook2App.h"
#include "WxAuiNotebook2Frame.h"

wxIMPLEMENT_APP(WxAuiNotebook2App);

bool WxAuiNotebook2App::OnInit()
{
    WxAuiNotebook2Frame* frame = new WxAuiNotebook2Frame("WxAuiNotebook2");
    frame->Show(true);
    return true;
}