5、消息过滤、消息通知与自定义消息
5.1消息过滤
我们想截取一个button的左键点击事件,方法如下:
1、 先button给自己安装一个过滤器
m_button->installEventFilter(this); |
这个设置的意思是button将this(这里是一个窗口)这个对象设置为自己的消息过滤器,那么所有经过button的消息都要先经过这个过滤器的eventFilter()函数。
如果没有过滤器要截取button的点击消息,则需要派生一个button的子类,在这个子类中调用event()函数进行截取。因为每个对象要处理的消息不一样,如果每个对象为了过滤某个消息就要派生一个新的类出来,不管是从工作量还是程序设计等角度来说都是不方便的。
比较简单的方法是这些对象都安装一个消息过滤器,这样每次消息来的时候都会先经过过滤器,将不需要的消息直接过滤掉就好。
2、重载过滤器的eventFilter()函数
booleventFilter(QObject*,QEvent*); |
boolMyWidget::eventFilter(QObject*obj,QEvent*ev) { if(obj==(QObject*)m_button&&ev->type()==QEvent::MouseButtonPress) { returntrue; } returnQWidget::eventFilter(obj,ev); } |
5.2消息通知notify()
boolnotify(QObject*,QEvent*)Q_DECL_OVERRIDE; |
notify函数是QApplication的成员函数,窗口会向应用程序通知正在处理的消息,通过这个函数,应用程序可以知道各个窗口当前要处理的消息。可以派生一个QApplication类,重载这个函数,获取程序当前正在处理的消息。
classMyApplication:publicQApplication { Q_OBJECT public: MyApplication(intargc,char**argv):QApplication(argc,argv) {}
boolnotify(QObject*,QEvent*); signals:
publicslots:
private: }; |
boolMyApplication::notify(QObject*obj,QEvent*ev) {
//if(obj==主窗口&&ev==左键) //{ //do... //} if(this->topLevelWidgets().count()>0) { QWidget*mainWnd=this->topLevelWidgets().at(0);
if(obj==(QObject*)mainWnd&&ev->type()==QEvent::MouseButtonPress) { qDebug()<<"mainwdisclicked"; } } returnQApplication::notify(obj,ev); } |
5.3自定义消息
5.3.1应用程序向指定对象发送消息
一个对象可以发消息给另一个对象。
在QEvent中已经定义了很多消息:
可以看出从1000开始到65535是用户自定义消息的范围,理论上用户可以自定义64535个消息。
QApplication有postEvent和sendEvent用于发送消息
发送消息:
app.postEvent(&w,newQEvent(QEvent::MyUser)); |
app.sendEvent(&w,newQEvent(QEvent::MyUser)); |
消息可以发送给任何QObject对象,post和send发送消息是有区别的,post是立马返回,是非阻塞的,send必须要等消息发完才返回,是阻塞的。
自定义消息没有虚函数可以重载,所以只能在event()函数中进行处理
boolMyWidget::event(QEvent*ev) { if(ev->type()==QEvent::MyUser) { qDebug()<<"Usereventiscoming"; } } |
5.3.1一个对象向另一个对象发送消息
QApplication类有一个全局的对象指针:qApp,这个指针和main函数中我们定义的app是一个对象。所以我们可以在一个对象的构造函数或者成员函数中调用qApp的pos方法发送消息给指定的对象。
qApp->postEvent(this,newQEvent(QEvent::MyUser)); |