Merge branch 'helloworld-doc'
Modernize "Hello world" page: Bind(), C++11 etc. Closes https://github.com/wxWidgets/wxWidgets/pull/317
This commit is contained in:
@@ -51,24 +51,25 @@ menu and a status bar in its constructor. Also, any class that wishes to
|
||||
respond to any "event" (such as mouse clicks or messages from the menu or a
|
||||
button) must declare an event table using the macro below.
|
||||
|
||||
Finally, the way to react to such events must be done in "handlers". In our
|
||||
sample, we react to three menu items, one for our custom menu command and two
|
||||
for the standard "Exit" and "About" commands (any program should normally
|
||||
implement the latter two). Notice that these handlers don't need to be neither
|
||||
virtual nor public.
|
||||
Finally, the way to react to such events must be done in "event handlers" which
|
||||
are just functions (or functors, including lambdas if you're using C++11)
|
||||
taking the @c event parameter of the type corresponding to the event being
|
||||
handled, e.g. wxCommandEvent for the events from simple controls such as
|
||||
buttons, text fields and also menu items. In our sample, we react to three menu
|
||||
items, one for our custom menu command and two for the standard "Exit" and
|
||||
"About" commands (any program should normally implement the latter two). Notice
|
||||
that these handlers don't need to be neither virtual nor public.
|
||||
|
||||
@code
|
||||
class MyFrame: public wxFrame
|
||||
{
|
||||
public:
|
||||
MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
|
||||
MyFrame();
|
||||
|
||||
private:
|
||||
void OnHello(wxCommandEvent& event);
|
||||
void OnExit(wxCommandEvent& event);
|
||||
void OnAbout(wxCommandEvent& event);
|
||||
|
||||
wxDECLARE_EVENT_TABLE();
|
||||
};
|
||||
@endcode
|
||||
|
||||
@@ -83,47 +84,31 @@ enum
|
||||
};
|
||||
@endcode
|
||||
|
||||
Notice that you don't need to define identifiers for the "About" and "Exit". We
|
||||
then proceed to actually implement an event table in which the events are
|
||||
routed to their respective handler functions in the class MyFrame.
|
||||
|
||||
There are predefined macros for routing all common events, ranging from the
|
||||
selection of a list box entry to a resize event when a user resizes a window on
|
||||
the screen. If @c wxID_ANY is given as the ID, the given handler will be
|
||||
invoked for any event of the specified type, so that you could add just one
|
||||
entry in the event table for all menu commands or all button commands etc.
|
||||
|
||||
The origin of the event can still be distinguished in the event handler as the
|
||||
(only) parameter in an event handler is a reference to a wxEvent object, which
|
||||
holds various information about the event (such as the ID of and a pointer to
|
||||
the class, which emitted the event).
|
||||
|
||||
@code
|
||||
wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
||||
EVT_MENU(ID_Hello, MyFrame::OnHello)
|
||||
EVT_MENU(wxID_EXIT, MyFrame::OnExit)
|
||||
EVT_MENU(wxID_ABOUT, MyFrame::OnAbout)
|
||||
wxEND_EVENT_TABLE()
|
||||
@endcode
|
||||
Notice that you don't need to define identifiers for the "About" and "Exit" as
|
||||
wxWidgets already predefines and the standard values such as wxID_ABOUT and
|
||||
wxID_EXIT should be used whenever possible, as they can be handled in a special
|
||||
way by a particular platform.
|
||||
|
||||
As in all programs there must be a "main" function. Under wxWidgets main is
|
||||
implemented using this macro, which creates an application instance and starts
|
||||
the program.
|
||||
implemented inside ::wxIMPLEMENT_APP() macro, which creates an application
|
||||
instance of the specified class and starts running the GUI event loop. It is
|
||||
used simply as:
|
||||
|
||||
@code
|
||||
wxIMPLEMENT_APP(MyApp)
|
||||
wxIMPLEMENT_APP(MyApp);
|
||||
@endcode
|
||||
|
||||
As mentioned above, wxApp::OnInit() is called upon startup and should be used
|
||||
to initialize the program, maybe showing a "splash screen" and creating the
|
||||
main window (or several). The frame should get a title bar text ("Hello World")
|
||||
and a position and start-up size. One frame can also be declared to be the top
|
||||
window. Returning @true indicates a successful initialization.
|
||||
main window (or several). As frames are created hidden by default, to allow
|
||||
creating their child windows before showing them, we also need to explicitly
|
||||
show it to make it appear on the screen. Finally, we return @true from this
|
||||
method to indicate successful initialization:
|
||||
|
||||
@code
|
||||
bool MyApp::OnInit()
|
||||
{
|
||||
MyFrame *frame = new MyFrame( "Hello World", wxPoint(50, 50), wxSize(450, 340) );
|
||||
MyFrame *frame = new MyFrame();
|
||||
frame->Show( true );
|
||||
return true;
|
||||
}
|
||||
@@ -134,8 +119,8 @@ menu items as well as a status bar to be shown at the bottom of the main
|
||||
window. Both have to be associated with the frame with respective calls.
|
||||
|
||||
@code
|
||||
MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
|
||||
: wxFrame(NULL, wxID_ANY, title, pos, size)
|
||||
MyFrame::MyFrame()
|
||||
: wxFrame(NULL, wxID_ANY, "Hello World")
|
||||
{
|
||||
wxMenu *menuFile = new wxMenu;
|
||||
menuFile->Append(ID_Hello, "&Hello...\tCtrl-H",
|
||||
@@ -154,7 +139,8 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
|
||||
|
||||
CreateStatusBar();
|
||||
SetStatusText( "Welcome to wxWidgets!" );
|
||||
}
|
||||
|
||||
... continued below ...
|
||||
@endcode
|
||||
|
||||
Notice that we don't need to specify the labels for the standard menu items
|
||||
@@ -163,6 +149,32 @@ translated) labels and also standard accelerators correct for the current
|
||||
platform making your program behaviour more native. For this reason you should
|
||||
prefer reusing the standard ids (see @ref page_stockitems) if possible.
|
||||
|
||||
We also have to actually connect our event handlers to the events we want to
|
||||
handle in them, by calling Bind() to send all the menu events, identified by
|
||||
wxEVT_MENU event type, with the specified ID to the given function. The
|
||||
parameters we pass to Bind() are
|
||||
|
||||
-# The event type, e.g. wxEVT_MENU or wxEVT_BUTTON or wxEVT_SIZE or one
|
||||
of many other events used by wxWidgets.
|
||||
-# Pointer to the member function to call and the object to call it on. In
|
||||
this case we just call our own function, hence we pass `this` for this
|
||||
object itself, but we could call a member function of another object too.
|
||||
And we could could also use a non-member function here, and, in fact,
|
||||
anything that can be called passing it a wxCommandEvent could be used here.
|
||||
-# The optional identifier allowing to select just some events of wxEVT_MENU
|
||||
type, namely those from the menu item with the given ID, instead of handling
|
||||
all of them in the provided handler. This is especially useful with the menu
|
||||
items and rarely used with other kinds of events.
|
||||
|
||||
@code
|
||||
... continued from above ...
|
||||
|
||||
Bind(wxEVT_MENU, &MyFrame::OnHello, this, ID_Hello);
|
||||
Bind(wxEVT_MENU, &MyFrame::OnAbout, this, wxID_ABOUT);
|
||||
Bind(wxEVT_MENU, &MyFrame::OnExit, this, wxID_EXIT);
|
||||
}
|
||||
@endcode
|
||||
|
||||
Here are the standard event handlers implementations. MyFrame::OnExit() closes
|
||||
the main window by calling Close(). The parameter @true indicates that other
|
||||
windows have no veto power such as after asking "Do you really want to close?".
|
||||
@@ -197,6 +209,17 @@ void MyFrame::OnHello(wxCommandEvent& event)
|
||||
}
|
||||
@endcode
|
||||
|
||||
@note In C++11 programs, it can be convenient to use unnamed lambdas instead of
|
||||
functions for event handlers, especially when handling events from the
|
||||
controls as this allows to keep the code creating the control and handling
|
||||
its event together in the same place. Here, for example, we could replace
|
||||
the wxID_EXIT handler with just
|
||||
|
||||
@code
|
||||
Bind(wxEVT_MENU, [=](wxCommandEvent&) { Close(true); }, wxID_EXIT);
|
||||
@endcode
|
||||
|
||||
|
||||
Here is the entire program that can be copied and pasted:
|
||||
|
||||
@code
|
||||
@@ -218,14 +241,12 @@ public:
|
||||
class MyFrame: public wxFrame
|
||||
{
|
||||
public:
|
||||
MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
|
||||
MyFrame();
|
||||
|
||||
private:
|
||||
void OnHello(wxCommandEvent& event);
|
||||
void OnExit(wxCommandEvent& event);
|
||||
void OnAbout(wxCommandEvent& event);
|
||||
|
||||
wxDECLARE_EVENT_TABLE();
|
||||
};
|
||||
|
||||
enum
|
||||
@@ -233,23 +254,17 @@ enum
|
||||
ID_Hello = 1
|
||||
};
|
||||
|
||||
wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
||||
EVT_MENU(ID_Hello, MyFrame::OnHello)
|
||||
EVT_MENU(wxID_EXIT, MyFrame::OnExit)
|
||||
EVT_MENU(wxID_ABOUT, MyFrame::OnAbout)
|
||||
wxEND_EVENT_TABLE()
|
||||
|
||||
wxIMPLEMENT_APP(MyApp);
|
||||
|
||||
bool MyApp::OnInit()
|
||||
{
|
||||
MyFrame *frame = new MyFrame( "Hello World", wxPoint(50, 50), wxSize(450, 340) );
|
||||
MyFrame *frame = new MyFrame();
|
||||
frame->Show( true );
|
||||
return true;
|
||||
}
|
||||
|
||||
MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
|
||||
: wxFrame(NULL, wxID_ANY, title, pos, size)
|
||||
MyFrame::MyFrame()
|
||||
: wxFrame(NULL, wxID_ANY, "Hello World")
|
||||
{
|
||||
wxMenu *menuFile = new wxMenu;
|
||||
menuFile->Append(ID_Hello, "&Hello...\tCtrl-H",
|
||||
@@ -268,6 +283,10 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
|
||||
|
||||
CreateStatusBar();
|
||||
SetStatusText( "Welcome to wxWidgets!" );
|
||||
|
||||
Bind(wxEVT_MENU, &MyFrame::OnHello, this, ID_Hello);
|
||||
Bind(wxEVT_MENU, &MyFrame::OnAbout, this, wxID_ABOUT);
|
||||
Bind(wxEVT_MENU, &MyFrame::OnExit, this, wxID_EXIT);
|
||||
}
|
||||
|
||||
void MyFrame::OnExit(wxCommandEvent& event)
|
||||
|
Reference in New Issue
Block a user