本教程原文鏈接:http://zetcode.com/gui/wxwidgets/firstprograms/
翻譯:瓶哥
日期:2013年11月27日星期三
主頁:http://www.cnblogs.com/pingge/
若有翻譯錯誤或者歧義請聯系我!
在這一章,我們將會概括介紹如何創建wxWidgets程序。我們將會創建第一個簡單的例子,展示如何顯示一個圖標。接下來我們將會用一個簡單的例子說明如何響應事件。最后,我們將會看到這些小部件是如何與wxWidgets程序進行交互的。
一個簡單的程序
首先我們創建一個非常簡單的wxWidgets程序。
simple.h

#include <wx/wx.h> class Simple : public wxFrame { public: Simple(const wxString & title); };
simple.cpp

#include "simple.h" Simple::Simple(const wxString & title) : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(250, 150)) { Centre(); }
main.h

#include <wx/wx.h> class MyApp : public wxApp { public: virtual bool OnInit(); };
main.cpp

#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

#include <wx/wx.h> class Icon : public wxFrame { public: Icon(const wxString & title); };
icon.cpp

#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

#include <wx/wx.h> class MyApp : public wxApp { public: virtual bool OnInit(); };
main.cpp

#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

/* XPM */ static const char * icon_xpm[] = { /* columns rows colors chars-per-pixel */ "32 32 6 1", " c black", ". c navy", "X c red", "o c yellow", "O c gray100", "+ c None", /* pixels */ "++++++++++++++++++++++++++++++++", "++++++++++++++++++++++++++++++++", "++++++++++++++++++++++++++++++++", "++++++++++++++++++++++++++++++++", "++++++++++++++++++++++++++++++++", "++++++++ ++++++++++", "++++++++ ............ ++++++++++", "++++++++ ............ ++++++++++", "++++++++ .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

#include <wx/wx.h> class Button : public wxFrame { public: Button(const wxString & title); void OnQuit(wxCommandEvent & event); };
button.cpp

#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(); // This sets the window to receive keyboard input Centre(); } void Button::OnQuit(wxCommandEvent & WXUNUSED(event)) { Close(true); }
main.h

#include <wx/wx.h> class MyApp : public wxApp { public: virtual bool OnInit(); };
main.cpp

#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

#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

#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

#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

#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

#include <wx/wx.h> class MyApp : public wxApp { public: virtual bool OnInit(); };
main.cpp

#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有一個指向靜態文本控件的指針。
在這部分的wxWidgets教程中,我們創建了一些簡單的程序。