Qt自定义事件的实现(军队真正干活,但要增加监军,大平台通知事件,事件内容自定义)

1.Qt中定义事件的长官:QEvent

      QEvent的任务就是定义一些事件类型Type,它们都定义在了一个enum里。这就是教程中告诉我们的要子类化QEvent,派生出MyEvent,然后在MyEvent中定义事件类型QEvent::Type。

     我们子类化的时候模仿一个QEvent就好了,而且是继承,好些都不用子类做了,看一下QEvent类中的成员变量和成员函数,就这些东西:

 

      好了,我们通过子类化QEvent,把派生出来的MyEvent看做长官,它定义了具体某个事件。下面看谁是信使。

2.Qt中传递事件的信使:QCoreApplication(QApplication继承自QCoreApplication)

     我们看看QCoreApplication中定义的一些函数,这些函数就是我们经常遇到的那些与传递事件和过滤事件有关的函数,见下图:

Public Functions:

Static Public Members:

扫描二维码关注公众号,回复: 2326606 查看本文章

    所以,到这里我们就可以明确了,你要用QCoreApplication的static public类型的函数入sendEvent或postEvent函数来传递送信,要注意:当使用sendEvent时,你的事件要在栈上建立,sendEvent会直接调用notify把事件传递给士兵,不走事件队列;而用postEvent时,你的事件要在堆上建立,即要用new来创建,postEvent会把你的事件追加进事件队列。你还可以通过重载notify来影响送信过程。

3.Qt中接收响应事件的军队:QWidget(这是Qt中的widget之母,诸如QMainWindow、QPushBUtton等等都是继承自QWidget)

      看到了吗?这些就是event handler,即事件处理函数,这是干活的那帮人。里面有我们熟悉的mousePressEvent()、keyPressEvent()等常用的事件处理函数,它们都是protected virtual 类型的,可以重载。所以呀,我们可以子类化QWidget,从而继承得到好些个event handler,当然也可以自己定义event handler!相当于自己创造士兵来响应事件。通过山寨QWidget,就可以创造自己的军队!

        还有一点就是,当事件到达军队的时候,要先审查再分发,审查就是要经过事件过滤,分发就是通过对经过审查的事件进行判断再把它分给那个相应的士兵这就又涉及到一个类QObject,这是Qt的万类之母,这个类中有两个函数一个是eventFilter(),另一个是event()。要先子类化QObject来创建一个监控者,这个监控者重载eventFilter(),来为军队过滤事件。然后还要在军队(QWidget)通过调用installEventFilter ( QObject * filterObj )来安装过滤器,参数中的filterOb即为监控者。最后在军队(QWidget)中重载event()来分发事件,把事件分给对应会干这个活的士兵(event handler)。

       好了,我理解的大体过程就是这样,我是Qt新手,可能有错的地方,希望路过的大牛能给与指正,我将不胜感激!

示例

#include <QtGui/QApplication>  
#include <QCoreApplication>  
#include <QEvent>  
#include <QObject>  
#include <QDebug>  
  
static const QEvent::Type MyEventType = (QEvent::Type)QEvent::registerEventType(QEvent::User+100);  
  
//长官  
class MyEvent: public QEvent  
{  
public:  
    MyEvent(Type MyEventType):QEvent(MyEventType){}  
};  
  
//信使  
class MySender: public QCoreApplication  
{  
public:  
    MySender(int argc,char *argv[]):QCoreApplication(argc,argv){}  
  
public:  
    bool notify(QObject *receiver, QEvent *event);  
  
};  
  
bool MySender::notify(QObject *receiver, QEvent *event)  
{  
    if(event->type() == MyEventType)  
    {  
        qDebug()<<"MyEventType is coming!";  
        //return true;  
        /*这里不能return true,因为重写notify就是在事件被向下传递之前截住它, 
        随便搞它,搞完了还得给QCoreApplication::notify向下传递,除非在mySender.notify 
        实现了事件向下传递的那一套。直接返回的话myArmy就收不到这个事件,因为执行完这个 
        mySender.notify的return true后,事件传递被人为的在半截终止了 
        (见Qt事件处理的五个层次http://blog.csdn.net/michealtx/article/details/6865891 ) 
        ,下面的myArmy的安装的过滤器和它自己的event都不会收到这个事件,更甭提最后干活 
        的myEventHandler了。所以在主函数中执行完mySender.sendEvent把myEvent 
        交给mySender.notify这个败家子儿后,就执行mySender.exec进入其它事件的循环了。这就是 
        问题http://topic.csdn.net/u/20111012/19/78036d16-c163-40f9-a05c-3b7d6f4e9043.html 
        出现的原因。感谢1+1=2大牛!非常感谢! 
        */  
    }  
    return QCoreApplication::notify(receiver,event);  
}  
  
//军队  
class MyArmy: public QObject  
{  
public:  
    void MyEventHandler(QEvent *event);  
    bool event(QEvent *event);  
};  
  
void MyArmy::MyEventHandler(QEvent *event)  
{  
    qDebug()<<"The event is being handled!";  
    event->accept();  
}  
  
bool MyArmy::event(QEvent *event)  
{  
    if(event->type() == MyEventType)  
    {  
        qDebug()<<"event() is dispathing MyEvent";  
        MyEventHandler(event);//调用事件处理函数  
        if((MyEvent*)event->isAccepted())  
        {  
            qDebug()<<"The event has been handled!";  
            return true;  
        }  
    }  
    return QObject::event(event);  
}  
  
//监控者  
class MyWatcher: public QObject  
{  
public:  
    bool eventFilter(QObject *watched, QEvent *event);  
};  
  
bool MyWatcher::eventFilter(QObject *watched, QEvent *event)  
{  
    if(event->type() == MyEventType)  
    {  
        qDebug()<<"I don't wanna filter MyEventType";  
        return false;  
    }  
    return QObject::eventFilter(watched,event);  
}  
  
  
int main(int argc, char *argv[])  
{  
    //QCoreApplication a(argc, argv);  
    MySender mySender(argc,argv);  
  
    MyArmy myArmy;  
    MyWatcher myWatcher;  
    myArmy.installEventFilter(&myWatcher);//安装事件过滤器  
  
    MyEvent myEvent(MyEventType);  
    mySender.sendEvent(&myArmy,&myEvent);  
    return mySender.exec();  
}  

运行结果:

猜你喜欢

转载自blog.csdn.net/lengyuezuixue/article/details/81153319
今日推荐