Qt 中的事件过滤器event filter

介绍

事件是继承 Qt 中 QEvent 类的对象。事件通过调用 QObject::event() 传递给从 QObject 继承的对象。事件传递意味着一个事件已经发生,QEvent 准确地表明了什么,QObject 需要响应。大多数事件都特定于 QWidget 及其子类。但是,有一些与图形无关的重要事件(例如套接字激活),这是 QSocketNotifier 用于其工作的事件。

一些事件来自窗口系统(例如QMouseEvent),一些来自其他来源(例如QTimerEvent),还有一些来自应用程序。Qt 像往常一样是对称的,因此您可以使用与 Qt 自己的事件循环完全相同的方式发送事件。

安装事件过滤器

事件过滤器是一种使用 QEvent 类捕获相关或感兴趣的事件的方法。如果它安装在小部件上,并让我们有机会在事件到达该小部件之前对其进行操作。每个 QObject 类都可以作为事件过滤器安装,它所要做的就是实现eventFilter(QObject *obj, QEvent *evt) 方法。如果我们想要阻止事件(因此它不会到达目标小部件),该方法应该返回“true”,如果它可以通过过滤器,则该方法应该返回 false。事件过滤最好的一点是,在许多情况下,它使我们免于对原生小部件进行子类化。这是一个计算 TextEdit 上退格点击次数的简单用例。

举个例子来理解

 下面的示例将为您提供有关事件过滤器的清晰图片。

main.cpp

#include "mainwindow.h"
#include <qapplication>
#include <qtgui>
#include <qdebug>

int main(int argc, char **argv)
{

  QApplication app(argc, argv);

  MainWindow mw;
  mw.show();

  app.exec();

}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <qmainwindow>
#include <qtextedit>
#include <qlabel>


namespace Ui {
class MainWindow;
}


class MainWindow : public QMainWindow
{
  public:
    MainWindow();


  protected:
    bool eventFilter(QObject *obj, QEvent *ev);


  private:
    QTextEdit *textEdit;
    QLabel    *bpCounter;
    QLabel    *bpTab;
    int        bpCnt;
    int        tabCnt;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QKeyEvent>

MainWindow::MainWindow()
{
  bpCnt = 0;
  tabCnt = 0;

  bpCounter = new QLabel(QString("Backspace Count: %1").arg(bpCnt));
  bpTab = new QLabel(QString("Tab Count: %1").arg(tabCnt));

  textEdit = new QTextEdit;
  setCentralWidget(textEdit);

  statusBar()->addWidget(bpCounter);
  statusBar()->addWidget(bpTab);
  textEdit->installEventFilter(this);
}

bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
  if (obj == textEdit) {
    if (event->type() == QEvent::KeyPress) {
      QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
      if ( keyEvent->key() == Qt::Key_Backspace ) {
        bpCounter->setText(QString("Backspace Count: %1").arg(bpCnt++));
      }
      else if ( keyEvent->key() == Qt::Key_Tab )
      {
        // 4 spaces
        textEdit->insertPlainText(QString().fill(' ', 4));
        bpTab->setText(QString("Tab Count: %1").arg(tabCnt++));
        return true;
      }
    }

    // pass the event to the widget
    return false;
  }
  else {
    // pass the event on to the parent class
    return QMainWindow::eventFilter(obj, event);
  }
};
分类: C++标签: