初学wxWidgets
初学wxWidgets
第⼀个程序
⾸先说明⼀下:本教程⽐较侧重于代码的实践,最好接合"Cross-Platform GUI Programming with wxWidgets"来读(⽹上有电⼦书,⾃⼰搜索⼀下),不过我写的还是⾃认为写的⽐较详细,单独阅读问题也应该不是很⼤.wxWidgets⽤户⼿册
是必备的,伟⼤的孙波同志正在翻译中⽂版 ,希望他可以坚持到底!⼤家可以在
邮件列表中到不完全翻译版,名字叫"wxWidgets 2.6.1: ⼀个可移植的C++和Python图形⽤户接⼝⼯具包(GUI toolkit)".
另外请⾼⼿们多多指教,更期待有志同道合者可以⼀起来完成这个教程.ok,我们开始吧!
wxWidgets库的,是⼀个结构类似于MFC的开源的C++库,它的特点是跨平台:⼀次编程便可以在从XP到Linux,苹果
机,WinCE等等操作系统上重新编译,运⾏.
安装和编译wxWidgets库我就不说了,⼤家可以参考Code Project上的"Introduction to wxWidgets"(作者:Priyank Bolia,期待哪位英⽂好的⾼⼿翻译⼀下)(我放在附件中了).
注意:"Introduction to wxWidgets"中路径设置的问题
环境变量"WXWIN"应该设置为"c:\"⽽不是"c:\\",然后包含⽬录的时候格式为"$(WXWIN)\include\"⽽不是"$(WXWIN)include\".我也提供了⼀
个VS2003修正版的"HelloWorld"的解决⽅案(本⽂的源代码只需直接复制到hello.cpp中便可编译运⾏).
照着这篇⽂章安装,编译,设置环境变量之后,就可以开始我们的程序了.我的
IDE是VS2003(Microsoft Visual Studio .NET 2003),wxWidgets库的版本是
2.6.1.
图 3.1. 第⼀个程序的截图
先了解⼀下"HelloWorld"的源代码
过程 3.1. 程序的调⽤顺序
1.⽤宏绑定main函数
2.MyApp::OnInit()
a.MyFrame初始化:设置界⾯布局,绑定按钮到事件表
b.通知计算机显⽰MyFrame
python入门教程非常详细电子书3.被按下按钮-->回调事件表中的相应函数
#include "wx/wx.h"
#include "mainico.xpm"//包含图标⽂件,格式为XPM,我在源代码之后有该格式的说明
//新建⼀个窗体
class MyFrame: public wxFrame
{
public:
MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
//事件处理函数
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
//这个呢,写过MFC的朋友⼀定眼熟,就是消息映射了,wxWidgets叫事件表
DECLARE_EVENT_TABLE()
};
vb如何设置inputbox函数的格式enum
{
ID_Quit,
ID_About,
};
//这⾥是事件的映射,当触发什么事件(如MENU_ABOUT)时候,调⽤什么函数(MyApp::OnAbout) BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(ID_Quit, MyFrame::OnQuit)
EVT_MENU(ID_About, MyFrame::OnAbout)
END_EVENT_TABLE()
//初始化程序
class MyApp: public wxApp
{
virtual bool OnInit();
};
//把main函数放在这⾥
IMPLEMENT_APP(MyApp)
//程序初始化的代码
bool MyApp::OnInit()
{
/*
wxT("Hello World")中"wxT"是⼀个宏,也可以写作"_T()",⽤于在编译时改变⽂字的编码.
⽐如,⼀个程序可以分别编译为ASCLL码版(只⽀持英⽂)和UTF-8版(⽀持多国语⾔)
*/
MyFrame *frame = new MyFrame( wxT("Hello World"),
wxPoint(299,250), wxSize(340,340) );
frame->Show(TRUE);
SetTopWindow(frame);
return TRUE;
}
MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
: wxFrame((wxFrame *)NULL, -1, title, pos, size)
//wxFrame中的初始化参赛以及其含义可以参见Gxl117翻译的《wxWindows 2⽤C++编写跨平台程序》(本⽂的附件中有){
SetIcon(wxIcon(mainico_xpm));//设置图标(mainico_xpm变量在mainico.xpm被声明)
wxMenu *menuFile = new wxMenu;//菜单条中⼀个条⽬
menuFile->Append( ID_About, wxT("&A菜单项--弹出窗⼝") );
menuFile->AppendSeparator();
menuFile->Append( ID_Quit, wxT("&Q退出") );
wxMenuBar *menuBar = new wxMenuBar;//菜单条
menuBar->Append( menuFile, wxT("&M菜单条中的条⽬" ));
SetMenuBar( menuBar );
CreateStatusBar();
SetStatusText(wxT( "欢迎使⽤wxWidgets!") );//状态栏
}
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
Close(TRUE);
}
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
wxMessageBox(wxT("消息框的⽂字:地球⼈,你好!"),
wxT("消息框的标题"),
fileupload是什么意思wxOK | wxICON_MASK ,
hibernate二级缓存是什么意思this);
}
XPM图像格式说明
把其他图⽚格式转换为XPM格式可以⽤⼀个免费软件XnView(有版),另外图⽚该程序的图标⼤⼩应该为16*16像素。⽤⽂本编辑器打开XPM⽂件后可以看到内容如下:
/* XPM */
static char *mainico_xpm[] = {
/* width height num_colors chars_per_pixel */
" 16 16 256 2",
/* colors */
"`` c #000000",
"`. c #173b03",
"`# c #62ce19",
...................等等
事件驱动(Event-Driven)
所谓事件驱动,简单地说就是你点什么按钮(即产⽣什么事件),电脑执⾏什么操
作(即调⽤什么函数).当然事件不仅限于⽤户的操作.
weWidgets的中所有可以处理事件的类都继承⾃wxEvtHandler,其中包含frames, buttons, menus, even documents,所有的窗体类(即从wxWindow继承的类)和程序类(application class).
这些类可以有⼀个事件表,⽤来绑定事件和被调⽤的函数(handler functions).
过程 3.2. 建⽴⼀个静态事件表(即编译时⽣成的事件表)的操作步骤
1.建⽴⼀个新类(直接或间接从wxEvtHandler继承)
2.为每个要处理的事件声明被调⽤的函数
3.在被处理的事件所在的类的声明中加⼊宏DECLARE_EVENT_TABLE
4.在宏BEGIN_ END_EVENT_TABLE(就是事件表)中将函数与
枚举的数字绑定(因为产⽣该类型的事件的按钮不唯⼀,要⽤枚举数来区
分);有些事件不必与枚举数绑定,因为产⽣该类型的事件的对象可以确定
(⽐如就是this).
例 3.1. ⼀个事件表
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU (wxID_ABOUT, MyFrame::OnAbout)
EVT_MENU (wxID_EXIT, MyFrame::OnQuit)
EVT_SIZE ( MyFrame::OnSize)
//不必与枚举数绑定,因为产⽣该类型的事件的对象是this
EVT_BUTTON (wxID_OK, MyFrame::OnButtonOK)
END_EVENT_TABLE()
5.在事件中指定被绑定的数字,wxWidgets会将其映射到对应的函数,并调
⽤函数
所有在事件表中被绑定的函数有相似的形式:返回值都是void,不是virtual函数,参数为wxCommandEvent类型
例 3.2. ⼀个事件表中被绑定的函数的声明
void OnButtonOK(wxCommandEvent& event);
⼀般说来,事件会从⼦类的事件表开始查询调⽤,如果没有到对应的调⽤,再依次查询其各个⽗类的事件表.但以下的事件例外,不会调⽤⽗类事件表wxActivate Event, wxCloseEvent, wxEraseEvent, wxFocusEvent, wxKeyEvent, wxIdleEvent, wxInitDialogEvent, wxJoystickEvent, wxMenuEvent, wxMouseEvent, wxMoveEvent, wxPaintEvent, wxQueryLayoutInfoEvent, wxSizeEvent, wxScrollWinEvent, and wxSysColourChangedEvent(都是些啥玩意?以后慢慢学)
让⼀个事件可以被多次处理
⼀个事件只能被处理⼀次,随即从消息队列(就是所有等待处理的事件)中被删除,也就是说,⼦类的事件表中处理过的事件,⽗类事件表中不会再次处理.如果想让该事件消息继续保留在消息队列中,可以使⽤wxCommandEven中的skip()函数.
skip实际⽤途举例:限制⽤户输⼊为数字,⽽具体的处理交付给⽗类去做.
例 3.3. helloWorld改版----wxCommandEven::skip()的⽰例
#include "wx/wx.h"
#include "mainico.xpm"
class MyFrame: public wxFrame
{
public:
MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
DECLARE_EVENT_TABLE()
hello spring是什么意思};
//新增代码
class MySkip:public MyFrame
{
public:
MySkip(const wxString& title, const wxPoint& pos, const wxSize& size):MyFrame(title,pos,size),i(1)
{};
void OnAbout2(wxCommandEvent& event)
{
i*=-1;
if (i>0) {
wxMessageBox(wxT("i>0,not SKip(不跳过)"));
}
vb程序设计在购买某物品时else
{
wxMessageBox(wxT("i<0,will SKip(将跳过)"));
event.Skip();
}
}
private:
int i;
DECLARE_EVENT_TABLE()
};
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论