Qt 事件过滤器
2017-01-25 20:35
204 查看
Qt 事件模型一个真正强大的特色是一个QObject的实例能够管理另一个QObject 实例的事件。
一个事件过滤器的安装需要下面2个步骤:
1、调用installEventFilter()注册需要管理的对象。
2、在eventFilter() 里处理需要管理的对象的事件。
伪代码如下:
class EventFilter : public QObject
{
public:
explicit EventFilter(QObject *parent = 0);
~EventFilter();
protected:
virtual bool eventFilter(QObject *obj, QEvent *event);
};
注意,如果你在事件过滤器中delete了某个接收组件,务必将返回值设为true。否则,Qt还是会将事件分发给这个接收组件,从而导致程序崩溃。
事件过滤器和被安装的组件必须在同一线程,否则,过滤器不起作用。另外,如果在install之后,这两个组件到了不同的线程,那么,只有等到二者重新回到同一线程的时候过滤器才会有效。
Qt提供了5个级别来处理和过滤事件.
1. 我们可以重新实现特定的event handler.
重新实现像mousePressEvent(), keyPressEvent()和paintEvent()这样的event Handler是目前处理event最普通的方式.
2. 我们可以重新实现QObject::event().
通过重新实现event(),我们可以在事件到达特定的event handler之前对它们作出处理. 这个方法主要是用来覆写Tab键的缺省实现. 也可以用来处理不同发生的事件类型,对它们,就没有特定的event handler. 当重新实现event()的时候,我们必须调用基类的event()来处理我们不显式处理的情况.
3. 我们可以安装一个event filter到一个单独的QObject.
一旦一个对象用installEventFilter注册了, 发到目标对象的所有事件都会先发到监测对象的eventFilter(). 如果同一object安装了多个event filter, filter会依次被激活, 从最近安装的回到第一个.
4. 我们可以在QApplication对象上安装event filter.
一旦一个event filter被注册到qApp(唯一的QApplication对象), 程序里发到每个对象的每个事件在发到其他event filter之前,都要首先发到eventFilter(). 这个方法对debugging非常有用. 也可以用来处理发到disable的widget上的事件, QApplication通常会丢弃它们.
5. 我们可以子类QApplication并重新实现notify().
Qt调用QApplication::notify()来发出事件. 在任何event filter得到之前, 重新实现这个函数是得到所有事件的唯一方法. event filter通常更有用, 因为可以有任意数目且同时存在的event filter, 但是只有一个notify()函数.
许多事件类型,包括鼠标和按键事件, 可以被传播. 如果一个事件没有在传到目标对象的过程中被处理,或者被目标对象本身处理, 整个事件处理过程会重复, 不过, 这次, 目标对象的parent作为新的目标对象. 从parent到parent,这样继续下去,知道事件被处理了,或者到达了顶层的对象.
一个事件过滤器的安装需要下面2个步骤:
1、调用installEventFilter()注册需要管理的对象。
2、在eventFilter() 里处理需要管理的对象的事件。
伪代码如下:
pFilterLineEdit->installEventFilter(new EventFilter(this));
class EventFilter : public QObject
{
public:
explicit EventFilter(QObject *parent = 0);
~EventFilter();
protected:
virtual bool eventFilter(QObject *obj, QEvent *event);
};
EventFilter::EventFilter(QObject *parent) : QObject(parent) { } EventFilter::~EventFilter() { } bool EventFilter::eventFilter(QObject *obj, QEvent *event) { QLineEdit *pLineEdit = qobject_cast<QLineEdit *>(obj); if (pLineEdit != NULL) { switch (event->type()) { case QEvent::MouseMove: case QEvent::MouseButtonDblClick: return true; case QEvent::KeyPress: { QKeyEvent *pKeyEvent = static_cast<QKeyEvent*>(event); if(pKeyEvent->matches(QKeySequence::SelectAll) || pKeyEvent->matches(QKeySequence::Copy) || pKeyEvent->matches(QKeySequence::Paste)) { return true; } } } } return QObject::eventFilter(obj, event); }
注意,如果你在事件过滤器中delete了某个接收组件,务必将返回值设为true。否则,Qt还是会将事件分发给这个接收组件,从而导致程序崩溃。
事件过滤器和被安装的组件必须在同一线程,否则,过滤器不起作用。另外,如果在install之后,这两个组件到了不同的线程,那么,只有等到二者重新回到同一线程的时候过滤器才会有效。
Qt提供了5个级别来处理和过滤事件.
1. 我们可以重新实现特定的event handler.
重新实现像mousePressEvent(), keyPressEvent()和paintEvent()这样的event Handler是目前处理event最普通的方式.
2. 我们可以重新实现QObject::event().
通过重新实现event(),我们可以在事件到达特定的event handler之前对它们作出处理. 这个方法主要是用来覆写Tab键的缺省实现. 也可以用来处理不同发生的事件类型,对它们,就没有特定的event handler. 当重新实现event()的时候,我们必须调用基类的event()来处理我们不显式处理的情况.
3. 我们可以安装一个event filter到一个单独的QObject.
一旦一个对象用installEventFilter注册了, 发到目标对象的所有事件都会先发到监测对象的eventFilter(). 如果同一object安装了多个event filter, filter会依次被激活, 从最近安装的回到第一个.
4. 我们可以在QApplication对象上安装event filter.
一旦一个event filter被注册到qApp(唯一的QApplication对象), 程序里发到每个对象的每个事件在发到其他event filter之前,都要首先发到eventFilter(). 这个方法对debugging非常有用. 也可以用来处理发到disable的widget上的事件, QApplication通常会丢弃它们.
5. 我们可以子类QApplication并重新实现notify().
Qt调用QApplication::notify()来发出事件. 在任何event filter得到之前, 重新实现这个函数是得到所有事件的唯一方法. event filter通常更有用, 因为可以有任意数目且同时存在的event filter, 但是只有一个notify()函数.
许多事件类型,包括鼠标和按键事件, 可以被传播. 如果一个事件没有在传到目标对象的过程中被处理,或者被目标对象本身处理, 整个事件处理过程会重复, 不过, 这次, 目标对象的parent作为新的目标对象. 从parent到parent,这样继续下去,知道事件被处理了,或者到达了顶层的对象.
相关文章推荐
- QT学习之阻拦退出程序函数以及事件过滤器的使用,以及文件的操作。
- QT父子窗口事件传递与事件过滤器
- Qt 键盘事件与消息过滤器
- Qt 事件过滤器
- QT 事件过滤器 eventFilter
- Qt之事件过滤器 截获消息通知 自定义消息处理事件解析.
- Qt事件过滤器
- QT 事件过滤器
- [Qt] 事件过滤器 [2013-06-17更新]
- Qt中使用事件过滤器来处理键盘焦点
- Qt的事件过滤器
- Qt入门(8)——事件和事件过滤器
- 详解 Qt 事件过滤器
- Qt 事件处理和事件过滤器的返回值总结
- qt事件过滤器
- Qt 事件过滤器
- Qt入门(8)——事件和事件过滤器
- QT之事件过滤器
- QT事件过滤器
- QT事件处理(二) 之 事件过滤器