在这一章,我们将会概括介绍如何创建wxWidgets程序。我们将会创建第一个简单的例子,展示如何显示一个图标。接下来我们将会用一个简单的例子说明如何响应事件。最后,我们将会看到这些小部件是如何与wxWidgets程序进行交互的。
一个简单的程序
首先我们创建一个非常简单的wxWidgets程序。
simple.h
1 2 3 4 5 6 7
| #include <wx/wx.h>
class Simple : public wxFrame { public: Simple(const wxString & title); };
|
simple.cpp
1 2 3 4 5 6 7
| #include "simple.h"
Simple::Simple(const wxString & title) : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(250, 150)) { Centre(); }
|
main.h
1 2 3 4 5 6 7
| #include <wx/wx.h>
class MyApp : public wxApp { public: virtual bool OnInit(); };
|
main.cpp
1 2 3 4 5 6 7 8 9 10 11 12
| #include "main.h" #include "simple.h"
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit() { Simple * simple = new Simple(_T("Simple")); simple->Show(true);
return true; }
|
这个小例子在屏幕上显示了一个小窗口,并且这个窗口是居中显示的。
Centre();
这个方法使这个窗口居中显示在屏幕上(水平和垂直)。
IMPLEMENT_APP(MyApp);
The code thar implements the application is hidden behind the macro.这是一段代码的复制粘贴,我们通常不用去关心。
应用程序图标
在这个例子中,我们给我们的程序提供一个图标,这是一个在窗口的左上角显示一个小图标的标准方法。这个图标是作为一个xpm格式文件被包含进这个程序。
icon.h
1 2 3 4 5 6 7
| #include <wx/wx.h>
class Icon : public wxFrame { public: Icon(const wxString & title); };
|
icon.cpp
1 2 3 4 5 6 7 8 9
| #include "icon.h" #include "icon.xpm"
Icon::Icon(const wxString & title) : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(250, 150)) { SetIcon(wxIcon(icon_xpm)); Centre(); }
|
main.h
1 2 3 4 5 6 7
| #include <wx/wx.h>
class MyApp : public wxApp { public: virtual bool OnInit(); };
|
main.cpp
1 2 3 4 5 6 7 8 9 10 11 12
| #include "main.h" #include "icon.h"
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit() { Icon * icon = new Icon(_T("Icon")); icon->Show(true);
return true; }
|
icon.xpm
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| static const char * icon_xpm[] = {
"32 32 6 1", " c black", ". c navy", "X c red", "o c yellow", "O c gray100", "+ c None",
"++++++++++++++++++++++++++++++++", "++++++++++++++++++++++++++++++++", "++++++++++++++++++++++++++++++++", "++++++++++++++++++++++++++++++++", "++++++++++++++++++++++++++++++++", "++++++++ ++++++++++", "++++++++ ............ ++++++++++", "++++++++ ............ ++++++++++", "++++++++ .OO......... ++++++++++", "++++++++ .OO......... ++++++++++", "++++++++ .OO......... ++++++++++", "++++++++ .OO...... ", "++++++++ .OO...... oooooooooooo ", " .OO...... oooooooooooo ", " XXXXXXX .OO...... oOOooooooooo ", " XXXXXXX .OO...... oOOooooooooo ", " XOOXXXX ......... oOOooooooooo ", " XOOXXXX ......... oOOooooooooo ", " XOOXXXX oOOooooooooo ", " XOOXXXXXXXXX ++++ oOOooooooooo ", " XOOXXXXXXXXX ++++ oOOooooooooo ", " XOOXXXXXXXXX ++++ oOOooooooooo ", " XOOXXXXXXXXX ++++ oooooooooooo ", " XOOXXXXXXXXX ++++ oooooooooooo ", " XXXXXXXXXXXX ++++ ", " XXXXXXXXXXXX ++++++++++++++++++", " ++++++++++++++++++", "++++++++++++++++++++++++++++++++", "++++++++++++++++++++++++++++++++", "++++++++++++++++++++++++++++++++", "++++++++++++++++++++++++++++++++", "++++++++++++++++++++++++++++++++" };
|
在我们的程序中我们显示了一个小的wxWidgetsLogo图标。
SetIcon(wxIcon(icon_xpm));
显示图标是上面这行代码的做的工作。XPM(X PixMap)是一种以ASCII码表现的图像格式。
一个简单的按钮
在接下来的这个例子中,我们在框架上创建了一个按钮。我们将会看到,如何建立一个简单的事件处理程序。
button.h
1 2 3 4 5 6 7 8 9
| #include <wx/wx.h>
class Button : public wxFrame { public: Button(const wxString & title);
void OnQuit(wxCommandEvent & event); };
|
button.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| #include "button.h"
Button::Button(const wxString & title) : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(270, 150)) { wxPanel * panel = new wxPanel(this, wxID_ANY);
wxButton * button = new wxButton(panel, wxID_EXIT, _T("Quit"), wxPoint(20, 20));
Connect(wxID_EXIT, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(Button::OnQuit));
button->SetFocus();
Centre(); }
void Button::OnQuit(wxCommandEvent & WXUNUSED(event)) { Close(true); }
|
main.h
1 2 3 4 5 6 7
| #include <wx/wx.h>
class MyApp : public wxApp { public: virtual bool OnInit(); };
|
main.cpp
1 2 3 4 5 6 7 8 9 10 11 12
| #include "main.h" #include "button.h"
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit() { Button * button = new Button(_T("Button")); button->Show(true);
return true; }
|
wxPanel * panel = new wxPanel(this, wxID_ANY);
首先我们创建一个wxPanel组件,这将被放置到一个wxFrame组件中。
wxButton * button = new wxButton(panel, wxID_EXIT, _T(“Quit”), wxPoint(20, 20));
我们建立了一个wxButton组件,它被放置在panel上,我们使用wxWidgets预定义的id:wxID_EXIT绑定这个按钮,按钮上面的标签文字是”Quit”,按钮被放置的坐标为(20, 20),坐标系的起点是左上角。
Connect(wxID_EXIT, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(Button::OnQuit));
如果我们点击这个按钮,一个wxEVT_COMMAND_BUTTON_CLICKED事件就会被触发,我们把这个事件和OnQuit()方法捆绑在一起,所以当我们点击按钮时,OnQuit()方法就会被调用。
Button->SetFocus();
我们把键盘的焦点设置到这个按钮上,所以如果我们按下回车键就相当于按钮被按下了。
Close(true);
在OnQuit()方法中,我们调用了Close()方法,这将会终结我们的应用程序。
组件之间的通信
知道各个组件之间如何互相通信很重要,请看下面这个例子。
panels.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| #include <wx/wx.h> #include <wx/panel.h>
class LeftPanel : public wxPanel { public: LeftPanel(wxPanel * parent);
void OnPlus(wxCommandEvent & event); void OnMinus(wxCommandEvent & event);
wxButton * m_plus; wxButton * m_minus; wxPanel * m_parent; int count; };
class RightPanel : public wxPanel { public: RightPanel(wxPanel * parent);
void OnSetText(wxCommandEvent & event);
wxStaticText * m_text; };
const int ID_PLUS = 101; const int ID_MINUS = 102;
|
panels.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| #include <wx/stattext.h> #include "communicate.h"
LeftPanel::LeftPanel(wxPanel * parent) : wxPanel(parent, wxID_ANY, wxPoint(-1, -1), wxSize(-1, -1), wxBORDER_SUNKEN) { count = 0; m_parent = parent; m_plus = new wxButton(this, ID_PLUS, _T("+"), wxPoint(10, 10));
m_minus = new wxButton(this, ID_MINUS, _T("-"), wxPoint(10, 60));
Connect(ID_PLUS, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LeftPanel::OnPlus));
Connect(ID_MINUS, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LeftPanel::OnMinus)); }
void LeftPanel::OnPlus(wxCommandEvent & WXUNUSED(event)) { count++;
Communicate * comm = (Communicate *)(m_parent->GetParent());
comm->m_rp->m_text->SetLabel(wxString::Format(_T("%d"), count)); }
void LeftPanel::OnMinus(wxCommandEvent & WXUNUSED(event)) { count--;
Communicate * comm = (Communicate *)(m_parent->GetParent());
comm->m_rp->m_text->SetLabel(wxString::Format(_T("%d"), count)); }
RightPanel::RightPanel(wxPanel * parent) : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(270, 150), wxBORDER_SUNKEN) { m_text = new wxStaticText(this, -1, _T("0"), wxPoint(40, 60)); }
|
communicate.h
1 2 3 4 5 6 7 8 9 10 11 12
| #include "panels.h" #include <wx/wxprec.h>
class Communicate : public wxFrame { public: Communicate(const wxString & title);
LeftPanel * m_lp; RightPanel * m_rp; wxPanel * m_parent; };
|
communicate.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #include "communicate.h"
Communicate::Communicate(const wxString & title) : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(290, 150)) { m_parent = new wxPanel(this, wxID_ANY);
wxBoxSizer * hbox = new wxBoxSizer(wxHORIZONTAL);
m_lp = new LeftPanel(m_parent); m_rp = new RightPanel(m_parent);
hbox->Add(m_lp, 1, wxEXPAND | wxALL, 5); hbox->Add(m_rp, 1, wxEXPAND | wxALL, 5);
m_parent->SetSizer(hbox);
this->Centre(); }
|
main.h
1 2 3 4 5 6 7
| #include <wx/wx.h>
class MyApp : public wxApp { public: virtual bool OnInit(); };
|
main.cpp
1 2 3 4 5 6 7 8 9 10 11 12
| #include "main.h" #include "communicate.h"
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit() { Communicate * communicate = new Communicate(_T("Communicate")); communicate->Show(true);
return true; }
|
在我们的例子中,我们有两个panel,一个左边一个右边,左边的有两个按钮,右边的有一个静态文本控件。按钮改变显示在右panel中的数字。问题是,我们是如何获得静态文本控件的指针的?
m_parent = parent;
在LeftPanel里我们存储了父组件的地址,这是一个wxPanel组件。
Communicate * comm = (Communicate *)m_parent->GetParent();
Comm->m_rp->m_text->SetLabel(wxString::Format(_T(“%d”), count));`
这两行是这个例子中最重要的两行,它展示了如何操纵那个放在右panel中的静态文本控件。首先我们取得了左panel和右panel的父窗口指针,这个父窗口组件有一个指向右panel的指针,并且右panel有一个指向静态文本控件的指针。