众所周知,包括Windows在内的所有GUI应用程序都是事件驱动的,那么在wxwidgets中如何基于事件驱动编程?包括以下内容:
n 简单的管理事件
n 插入事件控制
n 动态事件控制
n 自定义事件
事件驱动可以定义为:应用程序设置一个循环等待用户或其他的事件源产生事件,并将事件派发到相应的事件处理函数中进行处理。
Wxwidgets的事件定义方式同MFC基本相同,但是处理方式没有采用MFC的虚函数方式,而是采取了一种更加灵活的方式,wxWidgets中所有的类都继承自wxEvtHandler. wxEvtHandler包含一个EventTable告诉wxWidgets如何路由事件。所有的事件处理函数的形式都是一致的,返回void,这些事件处理函数全部是非虚的(not virtual),事件处理函数的传入参数根据事件的不同,是不同的派生自wxEvent的类,从而保证了处理函数能够从传入参数中获得更多的有用信息。
在wxwidgets 中有两种事件一种是可以回溯给父(window)事件处理函数处理的,一种是不发送的。发送的事件处理类基本都是wxCommandEvent或其子类。不发送的有:wxActivateEvent, wxCloseEvent, wxEraseEvent, wxFocusEvent, wxKeyEvent, wxIdleEvent,wxInitDialogEvent, wxJoystickEvent, wxMenuEvent, wxMouseEvent, wxMoveEvent,
wxPaintEvent, wxQueryLayoutInfoEvent, wxSizeEvent, wxScrollWinEvent 和wxSysColourChangedEvent 类
也称为静态事件管理,下面这个程序要在一个frame中建立一个Textbox和一个Button ,单击Button能够显示TextBox中的内容,通过这个程序来介绍静态事件管理的4个步骤,
l 建立一个类使之直接或简介的继承自wxEvtHandler
//定义一个资源ID,用来标识创建项目的唯一性
#define OKBTNID wxID_HIGHEST+21
//定义事件处理类,需要包含相应的事件处理函数
class MyFrame : public wxFrame |
l 在MyFrame中加入Button的Click处理函数
class MyFrame : public wxFrame
{
private:
wxButton* button;
public:
// 构造函数
MyFrame(const wxString& title);
// 事件处理函数,注意形参是wxEvent的派生类
void OnButtonOK(wxCommandEvent& event);
private:
// 声明event table
DECLARE_EVENT_TABLE()
}; |
l 在实现文件中建立映射
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_BUTTON(wxID_OK,MyFrame::OnButtonOK)
END_EVENT_TABLE() |
l 编写实际处理函数
void MyFrame::OnButtonOK(wxCommandEvent &event)
{
wxString msg;
msg.Printf("The value is %s",txtbox->GetValue());
wxMessageBox(msg,_T("OKButton"),wxOK,this);
}
|
编译、运行,通过编译后就可以显示出如下的界面:在textbox中输入一些内容,然后点击button就可以弹出一个对话框显示textbox中的内容了。上面的小例子显示一个标准事件的创建和控制的过程,一共4个步骤,简单回顾一下记住一些要点:
1) 创建事件处理的类,并在其中加入事件处理函数
2) 在事件处理类中加入事件处理表 使用宏 DECLARE_EVENT_TABLE()
3) 在实现文件中填写事件处理表,并将事件同处理函数进行对接利用到这么几个宏:BEGIN_EVENT_TABLE、END_EVENT_TABLE和EVT_XXXXXX
4) 编写处理函数。
下面是一些控制事件的要点:
l 负责事件处理的类必须直接或间接继承自wxEvtHandler
l 事件处理函数返回值一定是void,根据事件的类型不同,事件处理函数的传入参数的类型型也不同,但都继承自wxEvent,我们可以通过这个参数获得当前消息的各种信息
l 实际上每个EVT_XXXX宏都创建了一个wxEventTableEntry结构体并把他们存入由DECLARE_EVENT_TABLE定义的一个数组sm_eventTableEntries中,
l BEGIN_EVENT_TABLE中声明了一个由eventTableEntries建立的静态HASH表。并强制其init标志为TRUE,在今后的查询中wxwidgets会调用该HASH表的初始化过程将sm_eventTableEntries的内容填充到hash表中提高查询效率,这是一种延迟的机制,并不是在初始化的时候就建立该HASH表,而是在首次查询的时候进行。这部分的处理机制在今后的源代码分析中在详细的进行讨论。