- Introducing wxWidgets
- Installing wxWidgets
- First Example: Birds-Eye View
- Getting Into the Details: The Window
- Handling Events
- The Remaining Code
- Summary
First Example: Birds-Eye View
Without further ado, let’s take a look at a first example. I started with a sample included with wxWidgets called "minimal," and I made lots of changes. Listing 1 shows the resulting code.
Listing 1 Variation on the "minimal" sample.
#include <wx/wxprec.h> #include <wx/wx.h> #include <wx/textctrl.h> #include <iostream> class MyApp : public wxApp { public: virtual bool OnInit(); }; class MyFrame : public wxFrame { public: wxBookCtrl *book; wxListBox *listbox1; wxTextCtrl *textLog; MyFrame(const wxString& title); void OnButton1( wxCommandEvent &event ); void OnButton2( wxCommandEvent &event ); void OnListBoxDoubleClick( wxCommandEvent &event ); void OnQuit(wxCommandEvent& event); void OnAbout(wxCommandEvent& event); private: DECLARE_EVENT_TABLE() }; // Declare some IDs. These are arbitrary. const int BOOKCTRL = 100; const int BUTTON1 = 101; const int BUTTON2 = 102; const int LISTBOX1 = 103; const int TEXTBOX1 = 104; const int FILE_QUIT = wxID_EXIT; const int HELP_ABOUT = wxID_ABOUT; // Attach the event handlers. Put this after MyFrame declaration. BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_BUTTON(BUTTON1, MyFrame::OnButton1) EVT_BUTTON(BUTTON2, MyFrame::OnButton2) EVT_LISTBOX_DCLICK(LISTBOX1, MyFrame::OnListBoxDoubleClick) EVT_MENU(FILE_QUIT, MyFrame::OnQuit) EVT_MENU(HELP_ABOUT, MyFrame::OnAbout) END_EVENT_TABLE() IMPLEMENT_APP(MyApp) bool MyApp::OnInit() { MyFrame *frame = new MyFrame( _T("My wxWidgets Demo")); frame->Show(true); return true; } MyFrame::MyFrame(const wxString& title) : wxFrame(NULL, wxID_ANY, title) { SetIcon(wxICON(sample)); wxMenu *fileMenu = new wxMenu; wxMenu *helpMenu = new wxMenu; helpMenu->Append(HELP_ABOUT, _T("&About...\tF1"), _T("Show about dialog")); fileMenu->Append(FILE_QUIT, _T("E&xit\tAlt-X"), _T("Quit this program")); wxMenuBar *menuBar = new wxMenuBar(); menuBar->Append(fileMenu, _T("&File")); menuBar->Append(helpMenu, _T("&Help")); SetMenuBar(menuBar); CreateStatusBar(2); SetStatusText(_T("So far so good."), 0); SetStatusText(_T("Welcome."), 1); book = new wxBookCtrl(this, BOOKCTRL); wxPanel *panel = new wxPanel(book); new wxButton( panel, BUTTON1, _T("Button &1"), wxPoint(50,30), wxSize(100,30) ); new wxButton( panel, BUTTON2, _T("Button &2"), wxPoint(50,80), wxSize(100,30) ); book->AddPage(panel, _T("Tab1"), true); wxString choices[] = { _T("Washington"), _T("Adams"), _T("Jefferson"), _T("Madison"), _T("Lincoln"), _T("One"), _T("Two"), _T("Three"), _T("Four") }; panel = new wxPanel(book); listbox1 = new wxListBox( panel, LISTBOX1, wxPoint(0,0), wxSize(150,70), 9, choices, wxLB_SORT | wxLB_EXTENDED); book->AddPage(panel, _T("Tab2"), false); panel = new wxPanel(book); wxBoxSizer *mysizer = new wxBoxSizer( wxVERTICAL ); panel->SetSizer(mysizer); textLog = new wxTextCtrl(panel, TEXTBOX1, _T("Log\n"), wxPoint(0, 250), wxSize(100, 50), wxTE_MULTILINE); mysizer->Add(textLog, 1, wxEXPAND | wxALL, 5); book->AddPage(panel, _T("Debug"), false); } void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) { Close(true); } void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) { wxString msg; msg.Printf( _T("About.\n") _T("Welcome to %s"), wxVERSION_STRING); wxMessageBox(msg, _T("About My Program"), wxOK | wxICON_INFORMATION, this); } void MyFrame::OnButton1(wxCommandEvent& WXUNUSED(event)) { wxMessageBox("Click1", "Click", wxOK | wxICON_INFORMATION, this); } void MyFrame::OnButton2(wxCommandEvent& WXUNUSED(event)) { wxMessageBox("Click2", "Click", wxOK | wxICON_INFORMATION, this); } void MyFrame::OnListBoxDoubleClick( wxCommandEvent &event ) { *textLog << "ListBox double click string is: \n"; *textLog << event.GetString(); *textLog << "\n"; }
Before tearing apart the code in detail, let’s see what the program looks like when you run it. Figures 1, 2, and 3 show various views of the program’s main window.
Figure 1 The first tab contains two buttons.
Figure 2 The second tab contains a list box.
Figure 3 The third tab contains a text box for debugging output.
Now here’s a birds-eye view of the code again, before getting into the details. Notice the class called MyFrame. This class represents the main window for the program. What’s cool about wxWidgets is that you don’t have to make calls into a native API to create a window and then attempt to "attach" an instance of your own class to the window. (This separation between a window class and the actual window is always a problem when people develop a GUI framework; the people who designed wxWidgets did a great job of working out the kinks.)
Inside the MyFrame class are three member functions. These functions are called in response to various events. You can give these functions whatever names you want, but it’s typically best to use names that describe the event. Two of these functions are event handlers for button clicks, one is an event handler in response to a double-click on a list box item, and two are functions that handle menu clicks.
There’s also a class called MyApp. This is basically a controller that starts the whole system going. The class includes a virtual function called OnInit that gets called by the framework; inside this function, you place your code to create the window instance and show the window.