[wxWidget系列] wxWidget的事件机制

简介:

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()  使本次事件失效,相当于未发生


本文转自 zhenjing 博客园博客,原文链接:  http://www.cnblogs.com/zhenjing/archive/2011/04/20/2021821.html ,如需转载请自行联系原作者


相关文章
|
27天前
|
存储 安全 Java
事件的力量:探索Spring框架中的事件处理机制
事件的力量:探索Spring框架中的事件处理机制
28 0
|
9月前
|
前端开发 JavaScript
简述下 React 的事件代理机制?
简述下 React 的事件代理机制?
|
16天前
|
JavaScript 前端开发 开发者
事件处理:深入理解Vue的事件机制
【4月更文挑战第23天】Vue.js的事件处理机制是其核心特性之一,允许开发者响应用户操作。通过`v-on`(或简写`@`)指令绑定DOM事件到方法,当事件触发时执行相应代码。事件修饰符如`.stop`、`.prevent`等简化了常见逻辑。此外,Vue支持自定义事件,便于组件间通信,如子组件通过`$emit`触发事件,父组件使用`v-on`监听并处理。理解这些概念能帮助开发者更有效地控制Vue应用的事件流程。
|
2月前
|
存储 安全 Java
全面探索Spring框架中的事件处理机制
在现代应用程序中,各个组件之间的通信是至关重要的。想象一下,你的应用程序中的各个模块像是一个巨大的交响乐团,每个模块都是一位音乐家,而Spring事件机制就像是指挥家,将所有音乐家协调得天衣无缝。这种松耦合的通信方式使你的应用程序更加灵活、可维护,而且能够轻松应对变化。现在,让我们进入这个令人兴奋的音乐厅,探索Spring事件的世界。
|
IDE 开发工具 Android开发
使用rxjava创建一个rxbus事件处理框架
RxJava已经出现很多个年头了,但是依然被很多公司使用,如果现在还对RxJava了解的不够透彻, 可以看这个系列对它的分析:相信看完后你对它会有个更全面的认识。 这个系列主要从下面几个方面来讲解: **RxJava基本操作符使用** **RxJava响应式编程是如何实现的** **RxJava的背压机制及Flowable是如何实现背压的** **RxJava的线程切换原理
|
JavaScript 开发者
DOM 事件机制
DOM 事件机制
46 0
|
JavaScript 前端开发 程序员
DOM 事件模型或 DOM 事件机制
DOM 事件模型或 DOM 事件机制
110 0
|
存储 缓存 前端开发
react 事件机制03-事件注册
本文来说下 react 事件机制的注册过程,在这个过程中主要经过了哪些关键步骤。 文章涉及到的源码是基于 react15.6.1版本,虽然不是最新版本但是也不会影响我们对 react 事件机制的整体把握和理解。 这里都是我自己的理解,不会说非常细节的内容,而是会把大概的流程和原理性的内容进行介绍,做到对整体有个了解。
143 0
react 事件机制03-事件注册
|
前端开发
react 事件机制04-事件触发原理(完结)
本文继续接上一篇 react 事件机制03-事件注册 来说下 react 事件机制的事件触发过程,一起研究下在这个过程中主要经过了哪些关键步骤,本文也是react 事件机制的完结篇,希望本文可以让你对 react 事件触发的原理有一定的理解。
125 0
react 事件机制04-事件触发原理(完结)
|
JavaScript 前端开发
47、事件模型
浏览器的事件模型,就是通过监听函数(listener)对事件做出反应。
136 0