Qt自定义事件的实现

来源:互联网 发布:餐饮成本核算软件 编辑:程序博客网 时间:2024/06/06 02:24

作者:kakaka2011

转自:http://blog.csdn.net/love_gaohz/article/details/10510675


在Qt中我们会遇到两种事件一种是Qt中的系统时间了,另外一种就是Qt自定义事件。

Qt 的自定义事件主要的实现:

Qt 的事件处理,实际上是有五个层次:重定义事件处理函数,重定义event()函数,为单个组件安装事件过滤器,为QApplication安装事件过滤器,重定义QCoreApplication的notify()函数。这几个层次的控制权是逐层增大的。

重要函数:

virtual bool QCoreApplication::notify ( QObject * receiver, QEvent * event );

该函数会将 event 发送给 receiver,也就是调用 receiver->event(event),其返回值就是来自 receiver 的事件处理器。

QCoreApplication::sendEvent()或者QCoreApplication:;postEvent()的区别?
static bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event);

直接将 event 事件发送给 receiver 接受者,使用的是 QCoreApplication::notify() 函数。函数返回值就是事件处理函数的返回值。在事件被发送的时候,event 对象并不会被销毁。通常我们会在栈上创建 event 对象,例如:

[c++] view plaincopy
  1.    
  2. QMouseEvent event(QEvent::MouseButtonPress, pos, 0, 0, 0);  
  3. QApplication::sendEvent(mainWindow, &event);  

static void QCoreApplication::postEvent(QObject *receiver, QEvent *event);

将 event 事件及其接受者 receiver 一同追加到事件队列中,函数立即返回。
因为 post 事件队列会持有事件对象,并且在其 post 的时候将其 delete 掉,因此,我们必须在堆上创建event 对象。当对象被发送之后,再试图访问 event 对象就会出现问题(因为 post 之后,event 对象就会被 delete)。
当控制权返回到主线程循环是,保存在事件队列中的所有事件都通过 notify() 函数发送出去。
事件会根据 post 的顺序进行处理。如果你想要改变事件的处理顺序,可以考虑为其指定一个优先级。默认的优先级是 Qt::NormalEventPriority。
这个函数是线程安全的。
简单的说就是:sendEvent()会把event直接使用QCoreApplication的notify()发送给receiver,postEvent()把event追加到事件队列中最终也要调用notify(),notify()把事件分发给参数中的receiver,如果receiver安装了eventFilter,那么event会发给定义这个事件过滤器的监控者,如果这个event没有被过滤,那么这个event会被传给receiver的event()函数,event()函数再把这个event传给与其相应的事件处理函数(诸如keyPressEvent()之类的函数)。这些事件处理函数这才是真正响应event的函数,它们才是真正干活的,到这里算是处理完了。
引用别人的代码实现:

[c++] view plaincopy
  1.    
  2. #include <qcoreapplication>  
  3. #include <qevent>  
  4. #include <qobject>  
  5. #include <qdebug>  
  6.   
  7. static const QEvent::Type MyEventType = (QEvent::Type)QEvent::registerEventType(QEvent::User+100);  
  8.   
  9. //长官  
  10. class MyEvent: public QEvent  
  11. {  
  12. public:  
  13.     MyEvent(Type MyEventType):QEvent(MyEventType){}  
  14. };  
  15.   
  16. //信使  
  17. class MySender: public QCoreApplication  
  18. {  
  19. public:  
  20.     MySender(int argc,char *argv[]):QCoreApplication(argc,argv){}  
  21.   
  22. public:  
  23.     bool notify(QObject *receiver, QEvent *event);  
  24.   
  25. };  
  26.   
  27. bool MySender::notify(QObject *receiver, QEvent *event)  
  28. {  
  29.     if(event->type() == MyEventType)  
  30.     {  
  31.         qDebug()<<"MyEventType is coming!";  
  32.         //return true;  
  33.         /*这里不能return true,因为重写notify就是在事件被向下传递之前截住它, 
  34.         随便搞它,搞完了还得给QCoreApplication::notify向下传递,除非在mySender.notify 
  35.         实现了事件向下传递的那一套。直接返回的话myArmy就收不到这个事件,因为执行完这个 
  36.         mySender.notify的return true后,事件传递被人为的在半截终止了 
  37.         (见Qt事件处理的五个层次http://blog.csdn.net/michealtx/article/details/6865891 ) 
  38.         ,下面的myArmy的安装的过滤器和它自己的event都不会收到这个事件,更甭提最后干活 
  39.         的myEventHandler了。所以在主函数中执行完mySender.sendEvent把myEvent 
  40.         交给mySender.notify这个败家子儿后,就执行mySender.exec进入其它事件的循环了。这就是 
  41.         问题http://topic.csdn.net/u/20111012/19/78036d16-c163-40f9-a05c-3b7d6f4e9043.html 
  42.         出现的原因。感谢1+1=2大牛!非常感谢! 
  43.         */  
  44.     }  
  45.     return QCoreApplication::notify(receiver,event);  
  46. }  
  47.   
  48. //军队  
  49. class MyArmy: public QObject  
  50. {  
  51. public:  
  52.     void MyEventHandler(QEvent *event);  
  53.     bool event(QEvent *event);  
  54. };  
  55.   
  56. void MyArmy::MyEventHandler(QEvent *event)  
  57. {  
  58.     qDebug()<<"The event is being handled!";  
  59.     event->accept();  
  60. }  
  61.   
  62. bool MyArmy::event(QEvent *event)  
  63. {  
  64.     if(event->type() == MyEventType)  
  65.     {  
  66.         qDebug()<<"event() is dispathing MyEvent";  
  67.         MyEventHandler(event);//调用事件处理函数  
  68.         if((MyEvent*)event->isAccepted())  
  69.         {  
  70.             qDebug()<<"The event has been handled!";  
  71.             return true;  
  72.         }  
  73.     }  
  74.     return QObject::event(event);  
  75. }  
  76.   
  77. //监控者  
  78. class MyWatcher: public QObject  
  79. {  
  80. public:  
  81.     bool eventFilter(QObject *watched, QEvent *event);  
  82. };  
  83.   
  84. bool MyWatcher::eventFilter(QObject *watched, QEvent *event)  
  85. {  
  86.     if(event->type() == MyEventType)  
  87.     {  
  88.         qDebug()<<"I don't wanna filter MyEventType";  
  89.         return false;  
  90.     }  
  91.     return QObject::eventFilter(watched,event);  
  92. }  
  93.   
  94.   
  95. int main(int argc, char *argv[])  
  96. {  
  97.     //QCoreApplication a(argc, argv);  
  98.     MySender mySender(argc,argv);  
  99.   
  100.     MyArmy myArmy;  
  101.     MyWatcher myWatcher;  
  102.     myArmy.installEventFilter(&myWatcher);//安装事件过滤器  
  103.   
  104.     MyEvent myEvent(MyEventType);  
  105.     mySender.sendEvent(&myArmy,&myEvent);  
  106.     return mySender.exec();  
  107. }  
  108.   
  109. </qdebug></qobject></qevent></qcoreapplication>  
 

 解释:

大体的实现是按照

①自定义QEvent::Type  用到QEvent::registerEventType();这个函数。

②重写QCoreApplication::notify(QObject*receiver,QEvent*event)它主要负责把事件发给接受者。

③实现QObject 的eventFilter函数,进行事件的过滤。不过滤事件return false;

④重定义event()函数,重定义事件处理函数,处理函数中可以调用event->accept();event->ignore()正如它们的名字一样,前者用来告诉 Qt,这个类的事件处理函数想要这个事件;后者则告诉 Qt,这个类的事件处理函数不想要这个事件


0 0
原创粉丝点击