Introduction

In this tutorial we will show how to draw using wxWidgets.

Drawing APIs

wxWidgets provides two different drawing APIs:

wxDC

The wxDC (wxWidgets: wxDC Class Reference) class provides a common drawing API to draw on different output devices. It is the older API and better results will probably be achieved by using the more modern wxGraphicsContext class.

wxGraphicsContext

The wxGraphicsContext (wxWidgets: wxGraphicsContext Class Reference) class provides an API based on the modern drawing backends like GDI+, CoreGraphics and Cairo.

Drawing with wxPaintDC

The full source for this example is available from our GitHub repository: wxWidgetsTutorials/Drawing/Drawing1.

 File: Drawing/Drawing1/src/Drawing1Frame.h
#ifndef _TUTORIALS_WXWIDGETS_DRAWING1FRAME_H_
#define _TUTORIALS_WXWIDGETS_DRAWING1FRAME_H_

#include <wx/frame.h>

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

private:
    void OnPaint(wxPaintEvent& evt);

    wxDECLARE_EVENT_TABLE();
};

#endif
 File: Drawing/Drawing1/src/Drawing1Frame.cpp
#include "Drawing1Frame.h"
#include <wx/dcclient.h>

Drawing1Frame::Drawing1Frame(const wxString& title)
    : wxFrame(NULL, wxID_ANY, title)
{
    SetBackgroundColour(*wxWHITE);
}

void Drawing1Frame::OnPaint(wxPaintEvent& evt)
{
    wxPaintDC dc(this);

    dc.SetPen(*wxGREY_PEN);
    dc.SetBrush(*wxLIGHT_GREY_BRUSH);
    dc.DrawRectangle(10, 10, 50, 50);
}

wxBEGIN_EVENT_TABLE(Drawing1Frame, wxFrame)
    EVT_PAINT(Drawing1Frame::OnPaint)
wxEND_EVENT_TABLE()
Figure 1: The Drawing1 Application
 File: Drawing/Drawing1/src/Drawing1App.h
#ifndef _TUTORIALS_WXWIDGETS_DRAWING1APP_H_
#define _TUTORIALS_WXWIDGETS_DRAWING1APP_H_

#include <wx/app.h>

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

#endif
 File: Drawing/Drawing1/src/Drawing1App.cpp
#include "Drawing1App.h"
#include "Drawing1Frame.h"

wxIMPLEMENT_APP(Drawing1App);

bool Drawing1App::OnInit()
{
    Drawing1Frame* frame = new Drawing1Frame("Drawing1");
    frame->Show(true);
    return true;
}

Drawing with wxGraphicsContext

The full source for this example is available from our GitHub repository: wxWidgetsTutorials/Drawing/Drawing2.

 File: Drawing/Drawing2/src/Drawing2Frame.cpp
#include "Drawing2Frame.h"
#include <wx/dcclient.h>
#include <wx/graphics.h>

Drawing2Frame::Drawing2Frame(const wxString& title)
    : wxFrame(NULL, wxID_ANY, title)
{
    SetBackgroundColour(*wxWHITE);
}

void Drawing2Frame::OnPaint(wxPaintEvent& evt)
{
    wxPaintDC dc(this);

    wxGraphicsContext* gc = wxGraphicsContext::Create(dc);
    if (gc)
    {
        gc->SetPen(*wxGREY_PEN);
        gc->SetBrush(*wxLIGHT_GREY_BRUSH);
        gc->DrawRectangle(10, 10, 50, 50);
        gc->DrawEllipse(70, 10, 50, 50);
        delete gc;
    }
}

wxBEGIN_EVENT_TABLE(Drawing2Frame, wxFrame)
    EVT_PAINT(Drawing2Frame::OnPaint)
wxEND_EVENT_TABLE()
Figure 2: The Drawing2 Application
Figure 3: Comparison between wxDC and wxGraphics DC output
 File: Drawing/Drawing2/src/Drawing2Frame.h
#ifndef _TUTORIALS_WXWIDGETS_DRAWING2FRAME_H_
#define _TUTORIALS_WXWIDGETS_DRAWING2FRAME_H_

#include <wx/frame.h>

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

private:
    void OnPaint(wxPaintEvent& evt);

    wxDECLARE_EVENT_TABLE();
};

#endif
 File: Drawing/Drawing2/src/Drawing2App.h
#ifndef _TUTORIALS_WXWIDGETS_DRAWING2APP_H_
#define _TUTORIALS_WXWIDGETS_DRAWING2APP_H_

#include <wx/app.h>

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

#endif
 File: Drawing/Drawing2/src/Drawing2App.cpp
#include "Drawing2App.h"
#include "Drawing2Frame.h"

wxIMPLEMENT_APP(Drawing2App);

bool Drawing2App::OnInit()
{
    Drawing2Frame* frame = new Drawing2Frame("Drawing2");
    frame->Show(true);
    return true;
}