PyQt 事件处理机制

PyQt 事件处理机制

转载博文

一、 两种事件处理机制

PyQt 为事件处理提供了两种机制:高级的信号和槽机制,以及低级的事件处理程序(event handler)非常适合用于对用户希望执行行动作的关注,而不会在用户不同特殊需求的细节处理中越陷越深。信号和槽也可以用来对窗口部件的某些行为进行自定义。不过,要做出更为深人的研充时,特别是在创建不同的自定义窗口部件时,就需要使用低级的事件处理程序。

PyQt 提供了一系列的事件处理程序,某些关注于窗口部件的行为,比如那些处理键盘按下和鼠标事件的行为,而另些则关注于窗口部件的外观,比如那些处理绘制事件(paint event) 和重设尺寸大小事件(resize event)的行为等。

PyQt 的事件处理机制可以以我们所期望的逻辑方式进行工作。例如,如果用户在某个拥有键盘焦点的窗口部件上点击鼠标或者按下键盘,就可以给这个窗口部件一个事件。 如果该窗口部件可以处理这个事件,那么事情就到此为止。不过,如果该窗口部件不能处理这个事件,事件就会传递到该窗口部件的父窗口部件中 —— 是 PyQt父-子结构的另一大好处。 这样就可以把未处理事件从子窗口部件一直传递到父窗口部件直至顶层窗口部件,而如果还是没能处理掉这个事件,那么就会简单地予以扔掉。

二、五种拦截和处理事件的方式

PyQt 为拦截和处理事件提供了 5 种不同方式。头两种方法是应用最为频繁的,而剩下的其他方法则相较而言没有那么常用。

最为简单的方法就是重新实现特定的事件处理程序。不过截至目前,只见到过一个这样的例子:重新实现过窗口部件的 closeEvent()。正如在这一章和随后的章节中看到的,通过重新实现一些事件处理程序是可以控制窗口部件的行为的 —— 例如,可以重新实现 keyPressEvent()、PressEvent()、mousePressEvent() 和 mouseReleaseEvent()。通过重新实现 resizeEvent() 和 paintEvent(),也可以控制一个窗口部件的外观。 当重新实现这些事件时,通常不需要调用基类的事件,因为只是希望我们自己的代码能够仅作为调用事件处理程序的执行结果而已。

在任何特定事件处理程序调用之前,都会调用 event() 事件处理程序。重新实现这个方法可以允许我们处理那些不能在某一特定事件处理程序(特别是,对 Tab 键焦点转换行为的重新定义)中处理的事件,或者实现那些用于不存在明确事件处理程序的事件,比如QEvent.ToolBarChange。当需要重新实现这些处理程序时,可以对任何不是自己亲自处理的事件调用它们的基类实现。

第 3 种和第 4 种方法会用到事件过滤程序 (event filter)。 可以对任何 QObject 调用 installEventFilter()。这就意味着,对于 QObject 的全部事件来说,它们都会先传递到我们自己的事件过滤程序:在它们到达目标对象之前,可以抛弃或者修改这些事件中的任何一个。这一方法一种更为强大的版本是,在 QApplication 对象上安装一个事件过滤程序,尽管实践中这样做仅仅是用做程序的调试和处理那些发送给禁用窗口部件的鼠标事件。在一个对象或者 QApplication 上安装多个事件过滤程序也是可以的,此时,它们会按照安装时间从新到旧依次执行。

事件过滤程序提供了一种非常强大的事件处理方式,对于新的 PyQt 编程人员来说,通常需要对它们进行不断尝试。不过,还是建议尽量不要使用事件过滤程序,至少是在你具有丰富的 PyQt 编程经验之前要少使用它们。如果安装了非常多的事件过滤程序,应用程序的性能就会大打折扣;此外,与简单重新实现某一特定事件处理程序或者 event() 处理程序相比,这样做会大大增加代码的复杂性。这里不会看到任何事件过滤程序方面的例子,因为在常规 PyQt 编程中要尽量避免用到它们(而只有在创建自定义窗口部件时它们才会涉及),况且也确实很少有必要用到它们。

第 5 种方法是子类化 QApplication 并重新实现其 notify() 方法。这个方法会在任何事件过滤程序或者事件处理程序之前得到调用,因此它提供了终极控制能力。实践中,仅会在调试时才会用到这一方法, 即使如此,事件过滤程序的用法是相当灵活的。

转载至 《Python Qt Gui 快速编程 —— PyQt 编程指南》
作者 Mark Summerfield

点我回顶部

 
 
 
 
 
 
 
Fin.

扫描二维码关注公众号,回复: 12729812 查看本文章

猜你喜欢

转载自blog.csdn.net/Enderman_xiaohei/article/details/109801148