Qt5相对于Qt4 增长对事件accept()和ignore()函数。web
Qt 中有不少种事件:鼠标事件、键盘事件、大小改变的事件、位置移动的事件等等。对于事件的处理,咱们Qt 中使用相对应的机制。
event()函数
1. event()函数是一个 protected 的函数,这意味着咱们要想重写event(),必须继承一个已有的类。
2. 各个组件对事件处理是并发修改,仍是挨个修改呢?并发
bool Test::event(QEvent *e) { if (e->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast<QKeyEvent *>(e); if (keyEvent->key() == Qt::Key_Tab) { qDebug() << "You press tab."; return true; } } return QWidget::event(e); }
eventFilter()函数
app
virtual bool QObject::eventFilter ( QObject * watched, QEvent * event );
bool Test::eventFilter(QObject *object, QEvent *event) { if (object == target && event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); if (keyEvent->key() == Qt::Key_Tab) { qDebug() << "You press tab."; return true; } else { return false; } } return false; }
总结Qt 的事件处理
1. 重写paintEvent()、mousePressEvent()等事件处理函数。这是最普通、最简单的形式,同时功能也最简单。
2. 重写event()函数。event()函数是全部对象的事件入口,QObject和QWidget中的实现,默认是把事件传递给特定的事件处理函数。
3. 在特定对象上面安装事件过滤器。该过滤器仅过滤该对象接收到的事件。
4. 在QCoreApplication::instance()上面安装事件过滤器。该过滤器将过滤全部对象的全部事件,所以和notify()函数同样强大,可是它更灵活,由于能够安装多个过滤器。全局的事件过滤器能够看到 disabled 组件上面发出的鼠标事件。全局过滤器有一个问题:只能用在主线程。(受线程影响)
5. 重写QCoreApplication::notify()函数。这是最强大的,和全局事件过滤器同样提供彻底控制,而且不受线程的限制。可是全局范围内只能有一个被使用(由于QCoreApplication是单例的)。函数
class Label : public QWidget { public: Label() { installEventFilter(this); } bool eventFilter(QObject *watched, QEvent *event) { if (watched == this) { if (event->type() == QEvent::MouseButtonPress) { qDebug() << "eventFilter"; } } return false; } protected: void mousePressEvent(QMouseEvent *) { qDebug() << "mousePressEvent"; } bool event(QEvent *e) { if (e->type() == QEvent::MouseButtonPress) { qDebug() << "event"; } return QWidget::event(e); } }; class EventFilter : public QObject { public: EventFilter(QObject *watched, QObject *parent = 0) : QObject(parent), m_watched(watched) { } bool eventFilter(QObject *watched, QEvent *event) { if (watched == m_watched) { if (event->type() == QEvent::MouseButtonPress) { qDebug() << "QApplication::eventFilter"; } } return false; } private: QObject *m_watched; }; int main(int argc, char *argv[]) { QApplication app(argc, argv); Label label; app.installEventFilter(new EventFilter(&label, &label)); label.show(); return app.exec(); }
输出结果是:post
QApplication::eventFilter eventFilter event mousePressEvent
所以能够知道,全局事件过滤器被第一个调用,以后是该对象上面的事件过滤器,其次是event()
函数,最后是特定的事件处理函数。this
registerEventType()函数 ------- 用于自定义事件的注册spa
static int QEvent::registerEventType ( int hint = -1 );
发送方式:.net
static bool QCoreApplication::sendEvent(QObject *receiver,QEvent *event);
例子:线程
QMouseEvent event(QEvent::MouseButtonPress, pos, 0, 0, 0); QApplication::sendEvent(mainWindow, &event); static void QCoreApplication::postEvent(QObject *receiver,QEvent *event);
注意:在事件被发送的时候,event对象并不会被销毁。一般咱们会在栈上建立event对象code
参考资料:
http://www.devbean.net/2012/10/qt-study-road-2-event-summary/