wxpython's wxEvent.Skip() 解释

64 阅读3分钟

在学习 wxPython 时,遇到了一些问题,主要集中在第 3 章中对图 3.3 中 Skip() 菱形的解释。

在步骤 3 “定位绑定对象”中,书中写道:

huake_00257_.jpg 如果未找到对象的绑定器,则处理过程将向上遍历类层次结构以查找在对象超类中定义的绑定器——(1)这不同于下一步中在容器层次结构中进行的遍历。

但在下一步骤,步骤 4 “确定是否继续处理”中写道:

事件处理程序通过调用 wx.Event 方法 Skip() 来请求更多处理。如果调用了 Skip() 方法,则处理继续并且(2)在(3)超类中定义的任何处理程序都会在步骤中被找到并执行。Skip() 方法可以在处理程序中的任何位置调用。Skip() 方法在事件实例中设置一个标志,wxPython 会在处理程序方法完成后检查该标志。在清单 3.3 中,OnButtonClick() 没有调用 Skip(),因此在这种情况下,事件过程在处理程序方法结束时完成。其他两个事件处理程序确实调用了 Skip() (4)因此系统将继续搜索匹配的事件绑定,(5)最终调用本机小部件(如鼠标悬停事件)的鼠标进入和离开事件的默认功能。

我的问题与我在文章中用数字标记的段落相关: (1)据我的理解和一些其他谷歌材料,传播发生在容器层次结构中,而不是类层次结构中,这是正确的吗? (2)真的吗?执行任何处理程序?不是那些匹配实例和事件组合的吗? (3)这里的超类是否正确?它不应该 是父窗口吗? (4)我认为这一行与问题 2 相矛盾,因此可能没有执行任何处理程序,只执行那些与实例和事件组合匹配的处理程序? (5)什么是默认功能?它是如何调用的?

2、解决方案

  1. 当与某个对象关联的事件生成时,处理程序查找的顺序如下:

    • wxApp::FilterEvent()
    • 在对象本身上推送的任何事件处理程序。我甚至不确定这是否在 wxPython 中公开,并且无论如何都应不再使用。
    • 对象本身,从在最派生类中注册的处理程序开始,然后继续执行在基类中定义的处理程序。
    • 如果事件是“可传播的”(对于 wxCommandEvent 默认情况下是这样,但不是,比如 wxMouseEvent),并且如果对象是窗口,那么对象的父窗口,递归地。
    • wxTheApp 本身。
    • 最后,使用底层工具包级别上事件的默认处理程序。它做了什么(如果有的话)取决于确切的事件类型和平台,但对于某些事件,让它被调用非常重要,特别是对于焦点事件,你必须让默认的本机控件处理程序を取得它们才能更新它们的焦点状态。
  2. 那么 Skip() 呢?通常,在搜索时找到的第一个处理程序被使用,并且事件处理在那里停止。但是,如果处理程序在执行期间调用 event.Skip(),则跳过此事件处理程序,然后继续搜索。也就是说,重要的是要理解,即使 Skip() 是在事件对象上调用的,它也不会跳过事件。相反,它跳过调用它的事件处理程序。

    希望你现在明白为什么在 wxFocusEvent 处理程序中调用 event.Skip() 很重要。