wxWidget 的事件机制

wxWidget 通过在编译期生成静态的事件表来实现事件类的事件处理。所有想要使用事件处理机制的地方都需要继承 wxEvtHandler 类(直接或间接)。

由于 window 控件需要处理自身的 UI 时间,故 wxWidget 将实现为 exEvtHandler 的基类,这就意味着所有的 wxWidget 的控件均是事件类,可以直接定义事件表。

a) 定义事件表的基本步骤:

1) 定义一个直接或间接继承自 wxEvtHandler 的类;

2) 定义所需的事件处理函数,函数格式: void Func(wx***Event& evt);

3) 在类的定义中使用 DECLARE_EVENT_TABLE() 声明事件表;

4) 在 cpp 文件中使用 BEGIN_EVENT_TABLE( SourcePanel, wxPanel ) 和 END_EVENT_TABLE() 定义事件表。

5) 使用相应的事件宏在事件表中建立事件与处理函数的映射。

b) 窗口的事件查找流程:

当前窗口事件类 ->1 级继承的事件类 ->2 级继承事件类 ->….-> 父窗口事件类 …

上述的事件查找过程是建立在事件没有被处理的前提下。如果某个事件类处理了该事件,并没有调用 skip() ,那么该事件将被认为已经处理完毕,查找终止。

熟悉窗口的事件查找流程,对于有效处理事件极为关键。

使用者可以通过提前截获某事件,从而阻断后续的处理流程;使用者也可以提前截获事件,增加额外的事件处理逻辑 ( 需调用 skip) 。

c) wxWindow 类的内部事件处理机制:

每个窗口类的内部均维护一个事件表栈,在事件传递给某个窗口类时,窗口类将事件逐一匹配事件表栈中事件表,也就是说最后放入的事件表将最先被匹配。用户可以通过 wxWindow::PushEvnetHandler 来压入事件表,通过 PopEventHandler 弹出事件表。一定要确保事件表中的事件处理对象的生存期大于窗口对象的生存期,除非 PopEventHandler ,并删除了该事件对象。记住:窗口本身也是一个事件处理对象,并作为第一个 EventHandler 被压入事件表栈。

wxWindow 的处理机制决定了使用者可以通过,改变事件表栈的顺序临时或永久的改变图形界面的行为。用户可以通过自定义的 wxEvtHandler 类,截获窗口事件,从而实现增加处理逻辑或过滤窗口事件的行为。

d) 下述事件不会传给事件源控件的父窗口,即当前窗口有效:

wxActivate, wxCloseEvent, wxEraseEvent, wxFocusEvent, wxKeyEvent, wxIdleEvent, wxInitDialogEvent, wxJoystickEvent, wxMenuEvent, wxMouseEvent, wxMoveEvent, wxPaintEvent, wxQueryLayoutInfoEvent, wxSizeEvent, wxScrollWinEvent, wxSysColourChangedEvent 。

这么设计是因为这些控件仅对当前窗口有意义。当然这是 wxWidget 设计者的想法。在实际编程中,可能需要截获 wxMouseEvent , wxKeyEvent 等事件,并增加其他的处理逻辑,比如过滤相应的 key 事件等。有三种常见办法:

1) 重载窗口类,在新类中截获事件;

2) 重载 wxEvtHandler ,在新 Handler 中截获事件;见 wxWindow 类事件处理机制。

3) 使用动态的事件处理函数 Connect 。不常用,不介绍。

问题:如何在父窗口中截获子窗口的内部事件,如 wxMouseEvent ?

这个问题不难。根据上面的分析, 1) 重载窗口类并不现实,因为 wxMouseEvent 不会传给父窗口。 3) 动态事件处理机制可以实现,但是需要重载窗口类,重新 connect 事件与事件处理函数。 2) 重载 wxEvtHandler ,实现所需逻辑,并将该对象压入子窗口,从而达到事先截获子窗口事件的目的。个人感觉 2) 最为方便。

那么有个问题:可否直接将父窗口 Push 给子窗口呢?答案是:不行,虽然所有窗口均是 wxEvthandler 对象。为什么呢?因为所有的 wxWindow 对象对事件的处理都是极其复杂的,使用父窗口去拦截子窗口事件,会引起混乱,因为所有子窗口的事件都会首先传给父窗口。实践证实:将父窗口 Push 给子窗口会引发异常。

e) 窗口标识符

所有的 wxCommandEvent 均可以在多个窗口之间传递,如何实现特定窗口处理特定事件呢? wxWidget 使用窗口标识符来标识窗口,从而在事件系统中实现定位特定窗口的作用。窗口标识符并不要求系统唯一,仅仅需要在特定的上下文中唯一即可。

窗口标识符仅仅是要使事件处理机制能够定位特定窗口,从而实现事件与窗口的映射。这意味着并不是所有的事件都关心窗口 ID ,尤其是那些不传递给父窗口的事件。

假设 wxWidget 的事件处理机制是完备的,那么通过事件宏,即可判断该事件是否会传递给父窗口:需要映射窗口 ID 的事件宏意味着该事件会传递给父窗口,反之,不然。

f) 事件对象的常用接口

1) skip()   是否继续传递该事件 ( 继续处理 )

2) 传递参数:如 int , long , string , void* 等变量

3) wxNotifyEvent::veto()  使本次事件失效,相当于未发生

转载于:https://www.cnblogs.com/zhenjing/archive/2011/04/20/2021821.html

[wxWidget系列] wxWidget的事件机制相关推荐

  1. 玩转Google开源C++单元测试框架Google Test系列(gtest)之三 - 事件机制

    一.前言 gtest提供了多种事件机制,非常方便我们在案例之前或之后做一些操作.总结一下gtest的事件一共有3种: 1. 全局的,所有案例执行前后. 2. TestSuite级别的,在某一批案例中第 ...

  2. 「前端面试题系列7」Javascript 中的事件机制(从原生到框架)

    前言 这是前端面试题系列的第 7 篇,你可能错过了前面的篇章,可以在这里找到: 理解函数的柯里化 ES6 中箭头函数的用法 this 的原理以及用法 伪类与伪元素的区别及实战 如何实现一个圣杯布局? ...

  3. Web Control 开发系列(三) 解析IPostBackEventHandler和WebForm的事件机制

    WebForm最大的魅力大概就是它自己的一套事件处理机制了,要做一个好的Control,必须深入理解这套机制,只有这样才可以让我们的Control有一整套Professional的Event,而IPo ...

  4. .net组件开发系列之武术系列 武术招数 控件生命周期与控件事件机制

    .net组件开发系列之武术系列 武术招数 控件生命周期与控件事件机制一.控件生命周期 先回述上篇,可能表述没有不清晰,也可能跨度大了点,好的,我们来一个循序渐进过程,大家都知道,武术都有招术的,先出什 ...

  5. 深入剖析OkHttp系列(五) 来自官方的事件机制

    Event Events allow you to capture metrics on your application's HTTP calls. Use events to monitor: T ...

  6. 我也来说说js的事件机制

    原文链接:http://www.w3cfuns.com/notes/17398/8062de2558ef495ce6cb7679f940ae5c.html 学js,不懂事件机制,基本可以说学了js,就 ...

  7. 解析IPostBackEventHandler和WebForm的事件机制

    WebForm最大的魅力大概就是它自己的一套事件处理机制了,要做一个好的Control,必须深入理解这套机制,只有这样才可以让我们的Control有一整套Professional的Event,而IPo ...

  8. gtest之断言宏的使用以及三种事件机制

    前面简单的介绍了一下gtest以及在Windows下如何安装gtest,今天再介绍一下在Linux下该如何安装. 本文重点: 在Linux下如何安装gtest: gtest下断言宏的介绍: gtest ...

  9. android 事件机制总结

    http://www.cnblogs.com/sunzn/archive/2013/05/10/3064129.html http://www.cnblogs.com/sunzn/archive/20 ...

最新文章

  1. python 往excel 里面写数据
  2. 115 存至网盘 也有限制?
  3. 智慧医疗机器人的普及还需很长一段路要走!
  4. 《SQL Server企业级平台管理实践》读书笔记——关于SQL Server数据库的备份方式...
  5. java 怎么向串口发送指令_idea ssm项目java程序使用十六进制rxtx包向串口发送指令的方法...
  6. 亚马逊 各国站点 链接_使用Amazon S3和HTTPS的简单站点托管
  7. linux将所有文件生成lst_10行Python代码自动清理电脑内重复文件,解放双手!
  8. deeplung代码实现测试是卡住情况说明
  9. 老也有错?科技行业对大龄程序员的歧视
  10. python的追加_Python追加添加相同的数据
  11. 竞赛程序设计知识要点图谱
  12. 谜题40:不情愿的构造器
  13. mysql 修改密码
  14. Git、Svn等版本控制管理工具的使用总结(附idea整合git)
  15. 前端通过localstorage统计浏览量
  16. iOS小技能:模拟鼠标点击(针对Mac)
  17. 无法加载 MySQL ODBC 5.3 Unicode Driver ODBC 驱动程序的安装例程,因为存在错误代码126.
  18. 详解三极管NPN与PNP区别
  19. 交换机之恢复重置设备密码
  20. GBase 8c产品简介

热门文章

  1. 没来得及整理的一些网站
  2. hdfs 多租户_Hadoop多租户架构配置
  3. Build.VERSION类
  4. Android MuPDF 部署
  5. android 使用GridView实现Gallery的效果,并且从最左边开始
  6. 【运维安全】-MySQL手工注入
  7. 每天一算:Two Sum II
  8. 你知道大数据强大在哪里!!!你永远也不会猜到
  9. ASP.NET Core轻松入门之Middleware管道模型
  10. 利用单壁路由实现vlan间路由