Writing Your First Application-Adding A Button

From WxWiki
Jump to: navigation, search

Thanks for reading at least this far into the tutorial. In this lesson I will show you how to use a widget, or component, which you should be familiar with: the button! We'll also look at events, one of the more important parts of Gui programming, which gives plenty of power to wxWindows and makes it much easier to use than other libraries.

I'm going to use this paragraph to explain the importance of events. When you're using an application under windows or any multitasking OS you are always clicking buttons, using menus, etc. Whenever you do anything like that, an event is triggered and the operating system sends a message to the program. When a program is being initialized it tells the OS what needs to be done should one of these events occur, and the appropriate function is executed when an event is received. So when you click a button, your OS tells the program you are running that's what happened, the program tells the OS to execute a function, and voilà, the function is ran.

Here is the code for this lesson; it displays a window with one big button, which closes the window when clicked.

  #ifndef __BASE_H // Make sure to only declare these classes once
  #define __BASE_H
    class MainApp: public wxApp // MainApp is the class for our application
    { 
    // MainApp just acts as a container for the window,
    public: // or frame in MainFrame
      virtual bool OnInit();
    };
    
    class MainFrame: public wxFrame // MainFrame is the class for our window,
    {
    // It contains the window and all objects in it
    public:
      MainFrame( const wxString &title, const wxPoint &pos, const wxSize &size );
      wxButton *HelloWorld;
      void OnExit( wxCommandEvent& event );
  
      DECLARE_EVENT_TABLE()
    };
  
    enum
    {
      BUTTON_Hello = wxID_HIGHEST + 1 // declares an id which will be used to call our button
    };
 
  #endif
  #include <wx/wxprec.h>
  #ifndef WX_PRECOMP
    #include <wx/wx.h>
  #endif
  #include "base.h"
 
  IMPLEMENT_APP(MainApp) // Initializes the MainApp class and tells our program
  // to run it
  bool MainApp::OnInit()
  {
    // Create an instance of our frame, or window
    MainFrame *MainWin = new MainFrame(_T("Hello World!"), wxPoint(1, 1), wxSize(300,200));
    MainWin->Show(TRUE); // show the window
    SetTopWindow(MainWin); // and finally, set it as the main window
 
   return TRUE;
  } 
 
  BEGIN_EVENT_TABLE ( MainFrame, wxFrame )
    EVT_BUTTON ( BUTTON_Hello, MainFrame::OnExit ) // Tell the OS to run MainFrame::OnExit when
  END_EVENT_TABLE() // The button is pressed

  MainFrame::MainFrame(const wxString &title, const wxPoint &pos, const wxSize
    &size): wxFrame((wxFrame*)NULL,  - 1, title, pos, size)
  {
    HelloWorld = new wxButton(this, BUTTON_Hello, _T("Hello World"),
      // shows a button on this window
    wxDefaultPosition, wxDefaultSize, 0); // with the text "hello World"
  }
 
  void MainFrame::OnExit( wxCommandEvent& event )
  {
    Close(TRUE); // Tells the OS to quit running this process
  }

This is what the window looks like. Click the button to close it; compiling it should be just like the last lesson so I won't bother with that. Now, lets learn what we just did. What we just did:

 enum
 {
   BUTTON_Hello = wxID_HIGHEST + 1 // declares an id which will be used to call our button
 };

This code declares the id our button will use, setting it as wxID_HIGHEST + 1 to avoid it being the same value as one of the default IDs already declared by wxWindows.

  BEGIN_EVENT_TABLE ( MainFrame, wxFrame )
  EVT_BUTTON ( BUTTON_Hello, MainFrame::OnExit ) // Tell the OS to run MainFrame::OnExit when
  END_EVENT_TABLE() // The button is pressed

This code defines that when an event of the type EVT_BUTTON, or a button is clicked, occurs to a button holding the id of BUTTON_Hello, the function MainFrame::OnExit should be executed. There are many more event types, and many other widgets to have these events, but we'll learn more about that in the next lesson. Now here's some code from base.cpp:

  HelloWorld = new wxButton(this, BUTTON_Hello, _T("Hello World"),   // shows a button on this window
  wxDefaultPosition, wxDefaultSize, 0);                          // with the text "hello World"

This code adds a button with its parent set to "this" ( or MainFrame ), so that it shows up on this frame, its id set to BUTTON_Hello, which we declared earlier, some default values, the label set to "Hello World", and the last parameter, the default style. The last parameter could also be several different styles; here are a few (from the manual):

  • wxBU_LEFT: Left-justifies the label. WIN32 only.
  • wxBU_TOP Aligns the label to the top of the button. WIN32 only.
  • wxBU_RIGHT Right-justifies the bitmap label. WIN32 only.
  • wxBU_BOTTOM Aligns the label to the bottom of the button. WIN32 only.
  • wxBU_EXACTFIT Creates the button as small as possible instead of making it of the standard size (which is the default behaviour ).
  void MainFrame::OnExit()
  {
    Close(TRUE); // Tells the OS to quit running this process
  }

And our last bit of code, the function we told wxWindows to run when our button is clicked, is pretty simple. We just run the Close() command to quit the program. We shall see some more advanced reactions to these events later, such as in our next tutorial where we look at adding objects such as menu bars to our frame, and running events for those items. Challenge:

Modify this code to display a text control instead of a button, and display a message box when the user edits the text. ( Hint: Try the Manual if you get stuck! )


Solution to the last lesson: Simply copy+paste the following line in base.cpp so that it is run twice:

  // Create an instance of our frame, or window
  MainFrame *MainWin2 = new MainFrame (_("Hello World!"), wxDefaultPosition, wxSize(300, 200)); 
  // show the window
  MainWin2->Show(TRUE);