Cross platform App in wxWidgets

Mazhar Ahmed
The Devs Tech
Published in
5 min readApr 20, 2020

wxWidgets is a C++ library used to make Windows, Mac, Linux and other platform apps with a single codebase. It’s a C++ library but can be used from Python, PERL Haskell and Ruby too. Obviously many people are using it from these languages rather than C++. You may already have seen softwares which are built on top of wxWidget like Audacity, Website Painter etc. You can find more software built with it here.

Audacity, a sound editing application built with wxWidgets

You may wonder why we are so much interested towards writing a single codebase for multiple platforms. Why don’t we use more than one codebase for Windows, Mac, Linux and even more. Cross platform app means less programmer, less budget, less time, less hassle. We can fix bugs in one codebase and it will be fixed in different platforms. There are many facilities using cross platform development. There are also cons of using it like if the library or framework contains bugs then your app will inherit that bugs too.

Installation

If you are using Windows OS then installation is easy. They provides installer for windows. You can download the installer from the downloads section of the website. You will also need a C++ compiler to compile source files. So, please install Visual Studio too.

For Mac and Linux, there is no installer. You might get it via the package manager in some Linux distros. Like in Ubuntu we can simply run

sudo apt install libwxgtk3.0-gtk3-dev

But you can always download the source and build. They (wxWidgets) also promote that as this way the build system will be configured automatically. To do so, download the tar.bz2 file from the site or github. extract to a place in your machine say /home/your-name/wxwidgets. You need a C++ build environment to built this source. In linux gcc/g++ comes built in. You will also need the build-essential and lib-gtk packages in Linux. Simply install them on Ubuntu or Debian:

sudo apt update
sudo apt install build-essential
sudo apt install libgtk2.0-dev
sudo apt install libgtk-3-dev

On Centos, Amazon Linux, Fedora etc:

sudo yum groupinstall 'Development Tools'
sudo yum install gtk+-devel gtk2-devel gtk3-devel

For the Arch, Architect, Manjaro etc, it’s already included with the base installation. But you can install dependant packages like:

sudo pacman -Syy
sudo pacman -S libgtk2.0-dev
sudo pacman -S libgtk3-dev

On Mac you need to install Xcode with the command line build tool. Simple download the Xcode from App Store or run in the terminal:

xcode-select --install

And now follow the GUI like clicking the install button etc.

Now that you have essential tools installed with a C++ compiler on your system, you can build wxWidgets from the source. Run these commands in the /home/your-name/wxwidgets folder to build and install (it will take 20 ~ 60 minutes to complete the build process depending on your machine, and the process will eat your battery, so pls plug in your cable to a AC power source if you are using a laptop):

./configure
make
sudo make install
make clean

Also update the C++ library database on linux (Specially on Ubuntu) like:

sudo updatedb
sudo ldconfig

And now verify that if it is installed properly:

wx-config --version

Getting into xWidgets

I will be using a Mac for the rest of the article. For windows it’s the same just use Visual C++ compiler. I will make a new directory named the-devs-tech-wx in the folder I will make a new file named main.cpp which will be out main application class. Now let’s create a simple window with the title ‘The Devs Tech’. I will open the folder using VSCode by

open . -a Visual\ Studio\ Code
# or
open . -a "Visual Studio Code"

Now At first I will open the main.cpp and add the header file for the wxWidgets.

#include <wx-3.0/wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx-3.0/wx/wx.h>
#endif

Now I will inherit the wxApp class and make a new. Every app should do so

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

Now I will inherit the wxFrame because I want to show a window

class TheFrame : public wxFrame
{
public:
TheFrame(
const wxString &title,
const wxPoint &pos,
const wxSize &size
);
private:
void OnHello(wxCommandEvent &event);
void OnExit(wxCommandEvent &event);
void OnAbout(wxCommandEvent &event);
wxDECLARE_EVENT_TABLE();
};

Every menu should have an unique ID. That’s why I will now make an unique ID for the menu

enum
{
MENU_ID = 1 // or anything you want
};

Now let’s bind events to the common menus like

wxBEGIN_EVENT_TABLE(TheFrame, wxFrame)
EVT_MENU(MENU_ID, TheFrame::OnHello)
EVT_MENU(wxID_EXIT, TheFrame::OnExit)
EVT_MENU(wxID_ABOUT, TheFrame::OnAbout)
wxEND_EVENT_TABLE()
wxIMPLEMENT_APP(TheApp);

Let’s init the window now

bool TheApp::OnInit()
{
TheFrame *frame = new TheFrame(
"The Devs Tech",
wxPoint(50, 50),
wxSize(450, 340)
);
frame->Show(true); return true;
}

Now in the constructor of the window let’s write some elements

TheFrame::TheFrame(const wxString &title, const wxPoint &pos, const wxSize &size)
: wxFrame(NULL, wxID_ANY, title, pos, size)
{
wxMenu *menuFile = new wxMenu;
menuFile->Append(
MENU_ID,
"&Hello...\tCtrl-H",
"Help string shown in status bar for this menu item"
);
menuFile->AppendSeparator();
menuFile->Append(wxID_EXIT);
wxMenu *menuHelp = new wxMenu;
menuHelp->Append(wxID_ABOUT);
wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append(menuFile, "&File");
menuBar->Append(menuHelp, "&Help");
SetMenuBar(menuBar);
CreateStatusBar();
SetStatusText("Welcome from The Devs Tech!");
}

Now let’s define the button events we declared earlier

void TheFrame::OnExit(wxCommandEvent &event)
{
Close(true);
}
void TheFrame::OnAbout(wxCommandEvent &event)
{
wxMessageBox(
"This is a wxWidgets sample by The Devs Tech",
"About",
wxOK | wxICON_INFORMATION
);
}
void TheFrame::OnHello(wxCommandEvent &event)
{
wxLogMessage("Hello world from The Devs Tech!");
}

Our window is complete. Let’s compile it now

g++ `wx-config --cxxflags --libs` main.cpp

wx-config is a helpful tool which helps list / return the libraries and options for wxWidgets on your system. Here wx-config --cxxflags --libs returns needed flags and libraries to compile the file. So the output executable file is a.out (It is platform dependant, for windows it will not be a.out). Let’s run it

./a.out

And our window will be shown in a moment.

the window after compilation and running

Enhancement

Now we can add other enhancement to the window like add buttons and other controls. We can also add some built tool support like cmake, make etc. We can add README.md and other files too. We can make a nice directory structure for our project like a folder for the assets, image etc.

Source code used in this article is here https://github.com/mazhar266/Sample-wxWidgets-Window

That’s all for this article. In the next article we will see how to use other languages instead of C++ to reduce written codes.

--

--