Qt事件处理
Posted yu-900914
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt事件处理相关的知识,希望对你有一定的参考价值。
Qt事件处理
Qt事件处理的五个层次
Qt 应用程序 事件处理 的五个层次,同时也是时间流程如下图所示:
说明如下:
- sendEvent()会把event直接发送给QCoreApplication的notify(),postEvent()把event追加到事件队列中最终也要调用notify()。
- notify()把事件分发给参数中的receiver,如果receiver安装了eventFilter,那么event会发给定义这个事件过滤器的监控者,如果这个event没有被过滤,那么这个event会被传给receiver的event()函数。
- event()函数再把这个event传给与其相应的事件处理函数(诸如keyPressEvent()之类的函数)。这些事件处理函数这才是真正响应event的函数,它们才是真正干活的,到这里算是处理完了。
- 这个过程中,权限是由大到小的,不算sendEvent()和postEvent和事件循环,notify具有最大控制权,因为它最先见到event,我们可以重写notify()开始的这个处理链上的函数来响应event,从而进行相应的操作。
- 整个流程中,只有postEvent()和最后的事件处理函数是void类型,其它函数都是bool型。
QT 自定义事件
Qt自定义事件的实现也是按照五个层次的原理实现的
1 1 #include <QtGui/QApplication> 2 2 #include <QCoreApplication> 3 3 #include <QEvent> 4 4 #include <QObject> 5 5 #include <QDebug> 6 6 7 7 //声明、定义、注册自定义事件类型,事件ID为自定义事件ID起点QEvent::User +100=1100 8 8 static const QEvent::Type MyEventType = (QEvent::Type)QEvent::registerEventType(QEvent::User+100); 9 9 10 10 //长官 11 11 class MyEvent: public QEvent 12 12 { 13 13 public: 14 14 MyEvent(Type myeventtype):QEvent(myeventtype){} 15 15 }; 16 16 17 17 //信使 18 18 class MySender: public QCoreApplication 19 19 { 20 20 public: 21 21 MySender(int argc,char *argv[]):QCoreApplication(argc,argv){} 22 22 23 23 public: 24 24 bool notify(QObject *receiver, QEvent *event); 25 25 26 26 }; 27 27 28 28 bool MySender::notify(QObject *receiver, QEvent *event) 29 29 { 30 30 if(event->type() == MyEventType) 31 31 { 32 32 qDebug()<<"MyEventType is coming!"; 33 33 //return true; 34 34 /*这里不能return true,因为重写notify就是在事件被向下传递之前截住它, 35 35 随便搞它,搞完了还得给QCoreApplication::notify向下传递,除非在mySender.notify 36 36 实现了事件向下传递的那一套。直接返回的话myArmy就收不到这个事件,因为执行完这个 37 37 mySender.notify的return true后,事件传递被人为的在半截终止了 38 38 (见Qt事件处理的五个层次http://blog.csdn.net/michealtx/article/details/6865891 ) 39 39 ,下面的myArmy的安装的过滤器和它自己的event都不会收到这个事件,更甭提最后干活 40 40 的myEventHandler了。所以在主函数中执行完mySender.sendEvent把myEvent 41 41 交给mySender.notify这个败家子儿后,就执行mySender.exec进入其它事件的循环了。这就是 42 42 问题http://topic.csdn.net/u/20111012/19/78036d16-c163-40f9-a05c-3b7d6f4e9043.html 43 43 出现的原因。感谢1+1=2大牛!非常感谢! 44 44 */ 45 45 } 46 46 return QCoreApplication::notify(receiver,event); 47 47 } 48 48 49 49 //军队 50 50 class MyArmy: public QObject 51 51 { 52 52 public: 53 53 void MyEventHandler(QEvent *event);//自定义事件函数 54 54 bool event(QEvent *event); 55 55 }; 56 56 57 57 void MyArmy::MyEventHandler(QEvent *event) 58 58 { 59 59 qDebug()<<"The event is being handled!"; 60 60 event->accept(); 61 61 } 62 62 63 63 bool MyArmy::event(QEvent *event) 64 64 { 65 65 if(event->type() == MyEventType) 66 66 { 67 67 qDebug()<<"event() is dispathing MyEvent"; 68 68 MyEventHandler(event);//调用事件处理函数 69 69 if((MyEvent*)event->isAccepted()) 70 70 { 71 71 qDebug()<<"The event has been handled!"; 72 72 return true; 73 73 } 74 74 } 75 75 return QObject::event(event); 76 76 } 77 77 78 78 //监控者 79 79 class MyWatcher: public QObject 80 80 { 81 81 public: 82 82 bool eventFilter(QObject *watched, QEvent *event); 83 83 }; 84 84 85 85 bool MyWatcher::eventFilter(QObject *watched, QEvent *event) 86 86 { 87 87 if(event->type() == MyEventType) 88 88 { 89 89 qDebug()<<"I don‘t wanna filter MyEventType"; 90 90 return false; 91 91 } 92 92 return QObject::eventFilter(watched,event); 93 93 } 94 94 95 95 96 96 int main(int argc, char *argv[]) 97 97 { 98 98 //QCoreApplication a(argc, argv); 99 99 MySender mySender(argc,argv); 100 100 101 101 MyArmy myArmy; 102 102 MyWatcher myWatcher; 103 103 myArmy.installEventFilter(&myWatcher);//安装事件过滤器 104 104 105 105 MyEvent myEvent(MyEventType); 106 106 mySender.sendEvent(&myArmy,&myEvent); 107 107 return mySender.exec(); 108 108 }
要注意:
当使用sendEvent时,你的事件要在栈上建立,sendEvent会直接调用notify把事件传递给士兵,不走事件队列;而用postEvent时,你的事件要在堆上建立,即要用new来创建,postEvent会把你的事件追加进事件队列
以上是关于Qt事件处理的主要内容,如果未能解决你的问题,请参考以下文章