wxWidgets库基本概念及Hello world !程序

wxWidgets是一个跨平台的图形界面库,通过它可以编写在多种操作系统下都能运行的程序。同样是跨平台图形界面库的还有QT。本文先介绍一下wxWidgets库的基本概念,在文末通过书上的一个例程来实践所学知识。Hello world !程序的运行效果如下:

注:简单搜了一下,网上这方面内容现在也不少了,另外还有一本很系统的教材《Cross-Platform GUI Programming with wxWidgets》,这本书据说还有中文版。

1.应用程序类wxApp

每个程序都要建立一个wxApp的子类。在每个程序中,必须而且只能构造一个关于这个类的实例。

它有一个成员函数OnInit。在程序运行时,有一些窗口和结构需要初始化,而这个工作,就放在OnInit函数里。OnInit是BOOL型的,决定着程序的初始化是否成功。若返回值为true,则说明初始化成功,程序就进入事件循环,开始相应事件;而若返回的是false,程序初始化失败,直接退出。

2.构建wxApp类实例

在wxWidgets中,这个实例是通过宏IMPLEMENT_APP(MyApp)来完成构建的的,只要在程序里加上这段宏就可以了。另外,main函数是隐含在其中的,这里就是程序的入口处。

3.运行过程

首先程序找到应用程序类,调用其初始化函数,相应事件,收到退出事件退出。窗口是在初始化函数里创建的。而事件则是通过一张事件表对各个事件处理函数都分配了一个ID,而其它元素(按钮、菜单)根据ID,就可找到相应的处理函数。这两点在下文中逐个来说。

4.wxFrame窗口类

这个类是代表主窗口的,我们同样是派生一个子类。我们如何确定窗口的外观呢?通过构造函数,这里我们首先要其父类,来设定程序的标题和图标。而在它自己的构造里,则是要插入菜单、按钮、状态栏、文本框等控件。

这里以插入菜单为例,说明一下制作菜单栏的流程:建立菜单项—>菜单项加入内容—>创建标题栏—>将菜单项插入标题栏—>将标题栏插入主窗口。

我们派生的这个子类,除了通过其构造函数来设计窗口,还有两样重要任务。第一样是在其共有成员里声明了事件处理函数,这些函数仅有一个名字,尚未和ID绑定。

第二样是在私有成员里面有一个宏DECLARE_EVENT_TABLE(),他只是声明了一张事件表,而其具体内容要用宏单独定义。这张表的每一项只有两个元素,一个是ID,一个是事件处理函数,我们下面细说。

5.事件

我们在添加菜单项的那段代码中将会看到,每一个菜单项添加的同时,都为其分配了事件表里的一个ID,也就是都为其指定了一个处理函数。例如,在菜单项about中,指定了ID为wxID_ABOUT,而由事件表我们可查得,处理函数为MyFrame::OnAbout,由OnAbout具体内容我们可以看出,是弹出一个对话框。

6.Hello world ! 代码及其注释如下:

[code lang="c++"][/code]

#include"wx/wx.h"

//声明程序类
class MyApp : public wxApp
{
public:
//声明程序初始化函数
virtual bool OnInit();
};

//声明主框架(主窗口)类
class MyFrame : public wxFrame
{
public:
//构建函数
MyFrame(const wxString& title);
//事件处理函数
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
private:
//这个类处理事件
DECLARE_EVENT_TABLE()
};

//定义 MyApp& GetApp()
DECLARE_APP(MyApp)
IMPLEMENT_APP(MyApp)
//初始化程序
bool MyApp::OnInit()
{
//创建主窗口
MyFrame *frame = new MyFrame(wxT("Hello world !"));
//显示
frame->Show(true);
//开始事件循环
return true;
}

//主窗口(MyFrame)的事件表
BEGIN_EVENT_TABLE(MyFrame,wxFrame)
EVT_MENU(wxID_ABOUT,MyFrame::OnAbout)
EVT_MENU(wxID_EXIT,MyFrame::OnQuit)
END_EVENT_TABLE()

//定义OnAbout函数
void MyFrame::OnAbout(wxCommandEvent& event)
{
wxString msg;
msg.Printf(wxT("Hello World ! %s"),wxVERSION_STRING);
wxMessageBox(msg,wxT("About Minimal"),wxOK | wxICON_INFORMATION,this);
}

//定义OnQuit函数
void MyFrame::OnQuit(wxCommandEvent& event)
{
//关闭窗口
Close();
}

#include"mondrian.xpm"
//首先先调用其父类的构造函数
//没有父窗口,所以为NULL
//窗口标识wxID_ANY标识让wxWidgets自己选择一个
//标题
MyFrame::MyFrame(const wxString& title)
wxFrame(NULL,wxID_ANY,title)
{
//设置窗口图标
SetIcon(wxIcon(mondrian_xpm));
//建立菜单
wxMenu *fileMenu = new wxMenu;
wxMenu *helpMenu = new wxMenu;
//对菜单加入内容
helpMenu -> Append(wxID_ABOUT,wxT("&About...tF1"),wxT("Show about dialog"));
fileMenu -> Append(wxID_EXIT,wxT("E&xittAlt-x"),wxT("Quit this program"));
//把菜单插入菜单栏
wxMenuBar * menuBar = new wxMenuBar();
menuBar -> Append(fileMenu,wxT("&File"));
menuBar -> Append(helpMenu,wxT("&help"));
//将菜单栏插入窗口
SetMenuBar(menuBar);
//建立状态栏
CreateStatusBar(2);
SetStatusText(wxT("Welcome to wxWidgets!"));
}

[code][/code]