wxWidgets 事件学习

前言

wxWidgets事件连接有两种方式

1. 静态事件表(写法简单)
 2. 动态连接事件(适合动态生成控件的事件)

动态连接事件可以传递参数,适合自动生成一些控件

静态事件表

主窗口头文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef STATICEVENTTABLEFRAME_H
#define STATICEVENTTABLEFRAME_H

#include <wx/wx.h>
class StaticEventTableFrame: public wxFrame
{
public:
StaticEventTableFrame(wxFrame *frame, const wxString& title);
~StaticEventTableFrame();

protected:
//定义按钮的事件函数
void OnMyButton1(wxCommandEvent& event);
void OnMyButton2(wxCommandEvent& event);
private:
//定义静态事件表属性
DECLARE_EVENT_TABLE()
};

#endif // STATICEVENTTABLEFRAME_H

实现文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include "StaticEventTableFrame.h"
//定义按钮ID
#define BTN_ID 10021
#define BTN_2_ID 12000
BEGIN_EVENT_TABLE(StaticEventTableFrame, wxFrame)
// 以下都是接收button按钮发送的消息,消息类型为wxEVT_BUTTON,事件类型为wxCommandEvent
//连接消息和事件的时候,可以指定处理哪个ID的消息,-1代表全处理
//简便写法(连接事件和处理函数)
EVT_BUTTON(BTN_ID,StaticEventTableFrame::OnMyButton1)
//通用写法
EVT_COMMAND(BTN_2_ID,wxEVT_BUTTON,StaticEventTableFrame::OnMyButton2)

END_EVENT_TABLE()

StaticEventTableFrame::StaticEventTableFrame(wxFrame *frame, const wxString& title):wxFrame(frame,wxID_ANY,title)
{
//在界面上添加按钮
//因为重点不是布局,所以就直接用代码添加子控件了

wxButton* btn1 = new wxButton(this,BTN_ID,"我是按钮1",wxPoint(10,10),wxSize(100,30));
wxButton* btn2 = new wxButton(this,BTN_2_ID,"我是按钮2",wxPoint(10,10),wxSize(100,30));
wxBoxSizer* box = new wxBoxSizer(wxVERTICAL);
box->Add(btn1,1,wxALL,0);
box->Add(btn2,1,wxALL,0);
this->SetSizer(box);
}

StaticEventTableFrame::~StaticEventTableFrame()
{
//dtor
}
void StaticEventTableFrame::OnMyButton1(wxCommandEvent& event)
{
wxMessageBox("你点击了按钮1!!!");
}
void StaticEventTableFrame::OnMyButton2(wxCommandEvent& event)
{
wxMessageBox("你点击了按钮2!!!");
}

调用:

1
2
3
4
StaticEventTableFrame* frame = new StaticEventTableFrame(NULL,"静态事件");
frame->SetSize(800,600);
frame->Center();
frame->Show();

效果图:

动态连接事件

首先准备个数据包装类,继承wxObject:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 需要定义一个包装数据的类,以供动态连接事件传递参数
class Warp:public wxObject
{
public:
Warp(){}
Warp(wxString text){m_text = text;}
~Warp(){}
wxString GetText(){return m_text;}
private:
wxString m_text;
//将类加入到RTTI中,供类型转换使用,可以使用wxDynamicCast进行转换
DECLARE_DYNAMIC_CLASS(Warp)
};
//最好下面这句写在cpp文件里面
IMPLEMENT_DYNAMIC_CLASS(Warp,wxObject)

准备主窗口代码,头文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef DYNAMICEVENTTABLEFRAME_H
#define DYNAMICEVENTTABLEFRAME_H

#include <wx/wx.h>

class DynamicEventTableFrame: public wxFrame
{
public:
DynamicEventTableFrame(wxFrame *frame, const wxString& title);
~DynamicEventTableFrame();

protected:
//定义按钮的事件函数
void OnMyButton(wxCommandEvent& event);

private:

};

#endif // DYNAMICEVENTTABLEFRAME_H

实现文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include "DynamicEventTableFrame.h"

DynamicEventTableFrame::DynamicEventTableFrame(wxFrame *frame, const wxString& title):wxFrame(frame,wxID_ANY,title)
{
//在界面上添加按钮
wxGridSizer* grid = new wxGridSizer(2,5,0,0);
for(int i=0;i<10;i++)
{
wxString btnText = wxString::Format("按钮%d",i);
//创建按钮
wxButton* btn = new wxButton(this,wxID_ANY,btnText,wxPoint(10,10),wxSize(100,30));
//准备参数
Warp * warp = new Warp("你点击了"+btnText);
//连接事件,参数对象不需要手动释放内存,框架会帮我们释放
Connect(btn->GetId(),wxEVT_BUTTON,wxCommandEventHandler(DynamicEventTableFrame::OnMyButton),warp);
//设置布局
grid->Add(btn,1,wxALL,0);
}
this->SetSizer(grid);
}

DynamicEventTableFrame::~DynamicEventTableFrame()
{
//dtor
}
void DynamicEventTableFrame::OnMyButton(wxCommandEvent& event)
{
Warp* userData = wxDynamicCast(event.GetEventUserData(),Warp);
if(userData != NULL)
{
wxMessageBox(userData->GetText());
}
}

调用文件:

1
2
3
4
DynamicEventTableFrame* frame = new DynamicEventTableFrame(NULL,"动态连接事件");
frame->SetSize(800,600);
frame->Center();
frame->Show();

结尾

​ 一般常用的是静态事件表的方式,动态连接事件比较灵活,当业务比较复杂的时候,静态事件表不适合的时候可以使用动态连接事件。

评论