从QObject继承的函数可以调用installEventFilter函数来安装一个过滤器。
所谓安装一个过滤器就是指:调用installEventFilter的对象安装一个过滤器,所有到达自己的消息要先经过过滤器对象的处理,当过滤器对象处理后才能判定是否继续给自己或者让过滤器对象处理。
举例如下(拿qt文档上标准的例子来讲解下比较方便):
MainWindow重载了基类的eventFilter(QObject *obj, QEvent *event)函数,说明MainWindow是一个过滤器,他要调用了installEventFilter(MainWindow*)的对象的消息,如上的textEdit->installEventFilter(this);这句话就是说textEdit安装了一个过滤器MainWindow,发送给textEdit的消息会先经过MainWindow的过滤处理。因为eventFilter在处理发送的消息的时候第一个参数代表被查看的对象,第二个参数event代表了消息的类型(必要的时候重载QEvent,携带丰富的附加信息),所以过滤器可以处理所有自己需要的信息,前提是过滤器安装在其他对象上哟!
上面只是说了基本原理,下面说下自己实际应用过程中常用的比较有效的方法。
方法一:(基本应用)
原理:多个对象注册到同一个对象上代码如下(和上面的代码差不多,多添加了几个对象而已)
class MainWindow : public QMainWindow { public: MainWindow(); protected: bool eventFilter(QObject *obj, QEvent *ev); private: QTextEdit *textEdit;
QPushButtton * button;
QCheckBox * box; }; MainWindow::MainWindow() {
QHBoxLayout * layout = new QHBoxLayout(this);
textEdit = new QTextEdit;
button= new QPushButton;
box = new QCheckBox;
layout.addWidget(textEdit);
layout.addWidget(button); layout.addWidget(box);
#setCentralWidget(textEdit);
#安装过滤器了
textEdit->installEventFilter(this);
button->installEventFilter(this);
box->installEventFilter(this); }
#过滤器处理观察的对象的事件
bool MainWindow::eventFilter(QObject *obj, QEvent *event) { if (obj == textEdit) { if (event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event); qDebug() << "Ate key press" << keyEvent->key(); return true; } else { return false; } }
else if(obj == button)
{
#处理一些需要处理的有关button的事件
}
else if(obj == box)
{
#处理一些需要处理的有关box的事件
}
else { // pass the event on to the parent class return QMainWindow::eventFilter(obj, event); } }
方法二:(反向使用)
原理:一个对象安装多个过滤器,多个过滤器可以同时过滤此对象的消息,根据不同的消息类型来进行不同的处理
优缺点:可以夸多个库实现消息的相应,从而避免了通过信号槽方式逐级传递。
缺点:需要定义多个处理事件类,如下的event1和event2,每个事件基本都要定义独立的类。
DemoInstaller * install = new DemoInstaller;
class Event1:public QEvent
{
public:
Event1();
int data1;
int data2;
}
Event1::Event1()
:QEvent(Type(QEvent::User+10))
{
}
calss Event2:public QEvent
{
public:
int data3;
int data4;
}
Event2::Event2()
:QEvent(Type(QEvent::User+11))
{
}
class DemoFilter1: public QObject { public: DemoFilter1(); protected: bool eventFilter(QObject *obj, QEvent *ev); };
DemoFilter1::DemoFilter1()
{
install->installEventFillter(this);
}
bool DemoFilter1::eventFilter(QObject *obj, QEvent *ev)
{
if(obj==install)
{
if(ev.type()==QEvent::User+10)
{
Event1 * e1 = dynamic_cast<Event1*>(ev);
#处理e1.date1;
}
}
}
class DemoFilter2: public QObject { public: DemoFilter2(); protected: bool eventFilter(QObject *obj, QEvent *ev); }; DemoFilter2::DemoFilter2()
{
install->installEventFillter(this);
}
bool DemoFilter2::eventFilter(QObject *obj, QEvent *ev)
{
if(obj==install)
{
if(ev.type()==QEvent::User+11)
{
Event2 * e2 = dynamic_cast<Event2*>(ev);
#处理e2.date3;
}
}
}
class DemoInstaller: public QObject { public: DemoInstaller(); };
本人也是接触qt不久,如果大家还有好的使用方法的话,或者有关qt的技术内容,欢迎大家和我进行交流,QQ:634648088