Introduction to wxWidgets GUI programming with wxSmith
wxWidgets is a framework for cross-platform GUI development in C++. Started by Julian Smart at the Artificial Intelligence Applications Institute of Edinburgh University in 1992, the framework was ported to many platforms since then.
This article is intended to guide a beginer programer to install the needed resources and develope a single aplication with wxWidgets using Code::Blocks as the IDE for that.
What is wxWidgets
wxWidgets is a set of C++ libraries conforming a framework for multi-platform GUI developing. It gives an easy-to-use API very similar to the MFC API. Linking it with the appropiate library and compiles makes your applications look appropiate to the target platform. wxWidgets is a very complete framework with solutions for almost every thing you need but keeping the simplicity in the usage.
There are a number of options available for cross platform GUI development. Maybe one of the most popular is Java, but it's not an efficient alternative for some aplications. In C++ there is QT, a great framework, but as some disadvantages that have to be mentioned in first place its emulate the platform look, while wxWidgets uses the platform libraries for create the graphic interface; and in second place QT have a diferent approach using propietary layers between the code you write and the final C++ code that is compiled. Don´t mentiones about Microsoft Visual based frameworks that only works for windows, or some ones like mono.net that addas layers over layers.
In opposite of that examples wxWidgets is C++, so have this efficiency and doesn't adds any extra layer to your code. And it's a set of libraries so you can compile it with the C++ compiler you want, well, not every C++ compiler but the most common ones.
Other advantages and characteristics:
- It's still developed and have a lot of support and colavorative of the open source community.
- Its totaly free fir personal and comercial use.
- Have a lot of documentation online.
- Ease of learning. It's just C++.
- A lot of ready-to-use clases and libraries are available. Take a look here.
Let's get down to business. First of all we need the framework itself and an IDE to helpping us in the developign. Then we'll be able to do some magik and put a "Hello World" window in our screen.
I'll show the installation steps for windows but it's quite the same for other OS. I choose Code::Blocks IDE because its integration with wxWidgets and because it's free and available in stable version for windows and linux.
1. Downloading and installing Code::Blocks
You can download Code::Blocks binary realease from its own webpage. I recomend to download the mor recent stable mingw version, in this moment is codeblocks-13.12mingw-setup, that comes with de mingw compiler. Just download the installer and install it in the classic Windows-way. Probably you will have to add the path to the mingw/bin directory to the PATH envirvment variable. If someone have any trouble with this I can add mmore information about.
2. Downloading, installing and compiling wxWidgets
You may download the wxWidgets resources from its repository . Download the wxMSW installer or the ZIP because de installer is just a compressed folder. Download the stable realease 3.0.1 because it's the last stable version recomended for windows 7.
Once you've downloaded the installer or the ZIP file install/uncompress that in C:\. Open a command shell, the standard console in windows, change to the wxWidget build directory
The key here is to compile wxWidgets with the same compiler taht you will use later when developing. If you have installed the C::B IDE with mingw and add the path to the Envirvment Variable you don't have any problem with this.
where <wxwidgets> is the path you extracted the sources to (tipically C:\wxWidgets-3.0.1).
There you must tu execute the build command, that for the gcc compiler it'll be like this:
mingw32-make -f makefile.gcc BUILD=release SHARED=1 MONOLITHIC=1 UNICODE=1 CXXFLAGS=-fno-keep-inline-dllexport
Take a moment to see the compiling vars so you can choose the adecuate for you:
BUILD: the type of build of wxWidget. In most of cases you will use 'release' because you woun't debug wxWidgets itself. You can debug your own programs linking to a release version of wxWidgets.
SHARED: This variable define the linking type: dynamic linking (SHARED=1) and you have to share the required DLLs with your executable or static linking (SHARED=0) so you have to share only the executable. The excutable file generated by dynamic building has smaller size but you need the required DLLs in your PC in order to run it.
MONOLITHIC: Controls wheter a single DLL (MONOLITHIC=1) or multiple DLLs (MONOLITHIC=0) are built. With Monolithic built development is much easier and you have only one library to share with your executable, but with multifile built the linking process is more efficient because you avoid to linking with the entire wxWidget codebase.
UNICODE: Define wheter wxWidget and your programs use wide-character strings (UNICODE=1) or ANSI (UNICODE=0). It's strongly recomended to use the wxWidget _("string") and _T("string") macros to ensure that your hardcoded strings are in the correct format.
Now we have the wxWidgets builded so start developing some frame-based programs.
Creating a Project
1. First start Code::Blocks and select Create New Project.
2. In the project selection windows choose wxWidget
3. Now you have to choose the wxWidgets version. Be sure to choose the one you have installed. If you follow this instructions choose 3.0.x
4. Then will appear the name-the-project window. Here you enter the project name and location of the project. I was very vreative and named it HelloWorld
5. Now you have to select the GUI Builder, that is the tool that help you to create the graphical interface graphicaly. We will use xwSmith. And the application type, choose Frame Based.
6. The next windows wich appear asks you to select the location of wxWidgets in your computer. The better option is leave the global variable. When you click Next the global variable menu will appear, so there you have to entry the wxWidgets path in the base field. Then, if you change the location of wxWidgets you van edit the global variables from the Code::Blocks configuration.
7. Select the compiler. Just leave it by default (GCC compiler.
8. Now we have some configuration options. In the first section you have to match this options with the options you use when build wxWidgets.
Use wxWidgets DLL, check if you builded with SHARED=1.
wxWidgets is built as a monolithic library, check if you builded with MONOLITHIC=1.
Enable unicode, check if you builded with UNICODE=1.
For example, in the screenshot I leave unchecked the Use wxWidgets DLL because I builded wxWidgets with SHARED=0.
And check Advanced Options.
9. At least the last window, leave unchecked the Use __WXDEBUG__ and Debug wxWidgets lib option
It's probable that when you press the Finish button appears a dialog window telling that there's no debug build, click accept. You can debug with the release wxWidget build without any problem.
10. So here we are, with the development window in front of us. It's must be something like that:
Adding some stuff to our window
If you press Build and Run button (the one with the gear and the triangle (play symbol)) it displays a little window with a menu bar with two options, Menu and Help, and an empty status bar. But it's a good way to check if all its working fine.
Now I'll explain how to add a text label and a button to the window. I woun't go very deep in the many options and widgets you can use because the purpouse of this tutorial is to be a simple introduction to the framework. But I'll explain a few things about the development enviroment.
In the center we can see the design window. There we can edit the graphic interface or the code depending on the file we are editing. Just over the this window we have two buttons, one open the Menu Bar editor and the other one to open the Status Bar editor. But most important below the design window we have a set of buttons with the widgets that we can use in the development organized in categories.
In the left we see two diferent sections, the resource/file explorer up and the properties editor down.
The resource/file explorer let us find easyly the files or resources we want to edit. In the top are some tabs. With them we can change from dieferents views. The most importants are the Project tab and the Resources tab.
In the Project tree we can find all the files implied in the program. In the resource tree we can find the graphical resources.
The Properties Editor, below the file/resource navigator, will let us modifie some resource properties directly.
I will return to this later when we will be working on the window.
On the right we have a button bar wich affects some resources. The first four determine where the new resources will be added (on the pointer, inside the actual element and behind o in front of actual element). Then we have the crosed button for delete the current element and under that the Show Preview button. The lowest open the Properties Panel that has some placement and size options.
Adding some stuff
The first three steps that I will explain are the basic steps that you may use for every new project.
1. From the widgets menu below the design window select the Layout tab. Here we find the sizers. Sizers help us in the positioning and sizing the elements in the window. The sizers take care about resizing the elements and the inter element space when someone resize the window.
So from the Layout element select the basic one wxBoxSizer. This sizers organice the elements in one line horizontal or vertical. To add some element to eh window click on the element desired, the wxBoxSizer in this case, and the click inside the dotted panel in the design window. Now the window must look like this:
2. We can start now to throw some element into this but first we add some extra things. First, selecting the Standard tab of the widgets menu click on the wxPanel and then click inside the little square to add a panel to this. Be sure to have selected the boxSizer, to know this just look in the resource tree in the left, there you will see that the sizer was added to the tree, and when you select it in the graphical screen it be selected in the resource tree and viceversa. The wxPanel will add a fine background and add some characteristics to the window.
3. Now we add another wxBoxSizer but inside the Panel. So with the wxPanel selected click on the wxBoxSizer in the Layout tab and click again inside the box. Now the window may look like this image:
This steps constitute a good start up for the most of the programs. Now we add the interaction elements.
4. A Hello Worl program must show a Hello World text, so lets add it. In the Standard tab select the wxStaticText and click inside the box. This add a text label to the window.
If you look in the resource propertie editor at the left, you can see a table with some variables and values.
The first one is the label of the element. It's present in all the elements that show a text, originali it says "Label". By clicking on the right column (the value column) you can edit it so do this, click on the right column of the Label row and edit the text putting something ingenious like Hello World (you know, it gives bad luck to start with another text).
5. Now add some interaction. We will add a button to exit the window. So click on the wxButton button on the Standard tab. You will see that the window we are designing turns to blue, now when you pass the mouse cursor over the Label we added in the last step one of its sides become light blue, thats indicate in wich side the new resource will add because the wxStaticText can not have any element inside so automaticaly it is added in a side of it. Click in the right side to add the button.
Go to the properties editor and edit the label of the button, like we did with the Static Text label, and put a reference text. As aur button will close the windows I put 'Quit' on it.
6. You can try to build and run the program now by clicking on the Buil & Run button. It must appear a little window with the Hello World text and an useless button. So add some habilities to the button. To close the window you can click on the close button of the bar (the traditional cross) or go to File/Quit.
In the designer double click on the button we added and it bring us to the HelloWorldMain.cpp file (or the main file with the name youo gave to the project).
Maybe you hav to scroll down to find a function called something like
void HelloWorldFrame::OnButton1Click(wxCommandEvent& event)
This function take the button click event and do something with, it's called whenever you click on the button. Well, for now it isn't doing much so we'll edit this function to give saome funtionality. Soo add to the body of the function:
void HelloWorldFrame::OnButton1Click(wxCommandEvent& event)
The Close() function closes the window so now when you compile again you can close the window with our own button.
Here is the final result
Some final notes
If you select any resource of the design, one of the properties you can see in the properties editor are the size (width and height) and the position (x and y) variables. You can give values to them or just check the Default Size and Default Pos options so the layout manager choose the apropriate position and size for any element and the windows itself. It's the better option to start and for the most of the program we will make.
This was a very basic tutorial. Mi idea is to make more tutorial explaining other characteristics. But you can experiment by yourself, there a lot of resources to use.
Any suggestion, correction, doubt or comment are welcome. Thank you for reading.