Q.C人生

君子博学而日参省乎己,则知明而行无过矣

导航

wxWidgets学习笔记(2) 事件驱动(I)

Posted on 2010-12-16 16:50  ChanghW  阅读(2873)  评论(1编辑  收藏  举报

2.事件驱动

 众所周知,包括Windows在内的所有GUI应用程序都是事件驱动的,那么在wxwidgets中如何基于事件驱动编程?包括以下内容:

n  简单的管理事件  

n  插入事件控制

n  动态事件控制

n  自定义事件

 

2.1 wxwidgets事件概述

   事件驱动可以定义为:应用程序设置一个循环等待用户或其他的事件源产生事件,并将事件派发到相应的事件处理函数中进行处理。

   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

2.2 简单的管理事件:

也称为静态事件管理,下面这个程序要在一个frame中建立一个Textbox和一个Button ,单击Button能够显示TextBox中的内容,通过这个程序来介绍静态事件管理的4个步骤,

l  建立一个类使之直接或简介的继承自wxEvtHandler

//定义一个资源ID,用来标识创建项目的唯一性

#define OKBTNID   wxID_HIGHEST+21

//定义事件处理类,需要包含相应的事件处理函数

class MyFrame : public wxFrame

l  MyFrame中加入ButtonClick处理函数

 

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_TABLEEND_EVENT_TABLEEVT_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表,而是在首次查询的时候进行。这部分的处理机制在今后的源代码分析中在详细的进行讨论。