Qt 自定义事件的实现
初学Qt,用了Qt自带的事件,然后想怎么才能定义自己的事件呢?又如何使用自定义事件呢?看了篇文章,说先要子类化QEvent,然后定义自己的QEvent::Type,然后重写QWidget::event()函数,然后就可以调用QCoreApplication::sendEvent()或者QCoreApplication:;postEvent()发送事件就好了。但我比较笨,还是云山雾罩,不知道怎么下手。
怎么子类化QEvent?在哪里定义自己的QEvent::Type?在哪里重写QWidget::event()函数?在哪里调用QCoreApplication::sendEvent()或者QCoreApplication:;postEvent()发送事件?
在百度里搜索开了篇文章对我有启发http://bluemask.net/p/1215/ ,在google中搜索how to subclass QEvent也搜到一篇对我有启发的http://www.java2s.com/Code/Cpp/Qt/SubclassQEvent.htm 。(google的英文搜索真不错!)
后来我就想,那Qt的发明人是怎么定义事件的呢?其实站在Qt发明人的角度,QEvent就是他们的“自定义事件”!Ok!这就好办了!看看Qt发明人怎么定义的QEvent,看看他们怎么用自己定义的QEvent,不就回答了文章开头的俩问题了嘛!O(∩_∩)O~
我把整个过程总结为“长官定义事件”----->“信使传递事件”---->“军队接收并响应事件”。
我通过Qt Assistant查找那些与事件相关的类,总结如下:
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:
所以,到这里我们就可以明确了,你要用QCoreApplication的static public类型的函数入sendEvent或postEvent函数来传递送信,要注意:当使用sendEvent时,你的事件要在栈上建立,sendEvent会直接调用notify把事件传递给士兵,不走事件队列;而用postEvent时,你的事件要在堆上建立,即要用new来创建,postEvent会把你的事件追加进事件队列(详细过程请看http://blog.csdn.net/michealtx/article/details/6865891)。你还可以通过重载notify来影响送信过程。
注意C++:在函数内下列声明
一种是在栈上创建类对象,形式如下:CSomeClass someObject;
一种是在堆上创建(动态分配),形式如下:CSomeClass *pSomeObject = new CSomeClass();
具体一定要看这一篇文章:https://www.devbean.net/2014/02/cpp-create-object-on-heap-or-stack/ 《C++:在堆上创建对象,还是在栈上?》
3、Qt中接收响应事件的军队:QWidget(这是Qt中的widget之母,诸如QMainWindow、QPushBUtton等等都是继承自QWidget)
我们看看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新手,可能有错的地方,希望路过的大牛能给与指正,我将不胜感激!
什么话也不如来个例程给力!:
我建立的是Qt Console Application,工程叫MyEvent,下面是main.cpp中的代码:
#include <QtGui/QApplication>
#include <QCoreApplication>
#include <QEvent>
#include <QObject>
#include <QDebug> //声明、定义、注册自定义事件类型,事件ID为自定义事件ID起点QEvent::User +100=1100
static const QEvent::Type MyEventType = (QEvent::Type)QEvent::registerEventType(QEvent::User+); //长官
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();
}
运行结果:
好了,就这样了!可能有错误或不准确的地方!望路过的大牛指点!
转自:http://blog.csdn.net/MichealTX/article/details/6866094
Qt 自定义事件的实现的更多相关文章
- Qt 自定义事件(三种方法:继承QEvent,然后Send Post就都可以了,也可以覆盖customEvent函数,也可覆盖event()函数)
Qt 自定义事件很简单,同其它类库的使用很相似,都是要继承一个类进行扩展.在 Qt 中,你需要继承的类是 QEvent. 继承QEvent类,你需要提供一个QEvent::Type类型的参数,作为自定 ...
- Qt 自定义事件
Qt 自定义事件很简单,同其它类库的使用很相似,都是要继承一个类进行扩展.在 Qt 中,你需要继承的类是 QEvent. 继承QEvent类,你需要提供一个QEvent::Type类型的参数,作为自定 ...
- Qt自定义事件的实现(转)
原文:http://blog.csdn.net/michealtx/article/details/6866094 初学Qt,用了Qt自带的事件,然后想怎么才能定义自己的事件呢?又如何使用自定义事件呢 ...
- Qt自定义事件的实现(军队真正干活,但要增加监军,大平台通知事件,事件内容自定义)
初学Qt,用了Qt自带的事件,然后想怎么才能定义自己的事件呢?又如何使用自定义事件呢?看了篇文章,说先要子类化QEvent,然后定义自己的QEvent::Type,然后重写QWidget::event ...
- Qt 自定义事件详细实例(继承QEvent,然后QCoreApplication::postEvent()、sendEvent())
创建用户事件 创建一个自定义类型的事件,首先需要有一个事件号,其值通常大于QEvent::User.为了传递事件信息,因此必须编写自定义的事件类,该事件类从QEvent继承. 编写用户事件:编写用户事 ...
- Qt 学习之路:自定义事件
尽管 Qt 已经提供了很多事件,但对于更加千变万化的需求来说,有限的事件都是不够的.例如,我要支持一种新的设备,这个设备提供一种崭新的交互方式,那么,这种事件如何处理呢?所以,允许创建自己的事件 类型 ...
- Qt 学习之路 2(23):自定义事件
Qt 学习之路 2(23):自定义事件 豆子 2012年10月23日 Qt 学习之路 2 21条评论 尽管 Qt 已经提供了很多事件,但对于更加千变万化的需求来说,有限的事件都是不够的.例如, ...
- Qt的事件模型(5种使用办法,通常重新实现event handler即可。只有定义控件才需要管理信号的发射)
Qt的事件模型 1.事件的概念 应用程序对象将系统消息接收为 Qt 事件.应用程序可以按照不同的粒度对事件加以监控.过滤并做出响应. 在 Qt 中,事件是指从 QEvent继承 的对象.Qt将事件发送 ...
- paip.提升用户体验---c++ qt自定义窗体(1)---标题栏的绘制
源地址:http://blog.csdn.net/attilax/article/details/12343625 paip.提升用户体验---c++ qt自定义窗体(1)---标题栏的绘制 效果图: ...
随机推荐
- PLSQL_数据结构类型的解析(概念)
2014-06-02 Created By BaoXinjian
- AOE网与关键路径简介
前面我们说过的拓扑排序主要是为解决一个工程能否顺序进行的问题,但有时我们还需要解决工程完成需要的最短时间问题.如果我们要对一个流程图获得最短时间,就必须要分析它们的拓扑关系,并且找到当中最关键的流程, ...
- WebBrowser无法显示招商银行password输入控件的问题
本文由CharlesSimonyi发表于CSDN博客:http://blog.csdn.net/charlessimonyi/article/details/30479131转载请注明出处 之前就看到 ...
- 关于阿里云centos 2.6下手机表情输入后无法保存到mysql数据库的问题调研及mysql版本从5.1升级到5.7的全过程纪要
近日在开发手机app的评论功能时,输入表情文字,保存后提示数据库保存失败.错误日志片段如下 caused by: java.sql.SQLException: Incorrect string val ...
- 上传一个 游戏server架构图
- 17monipdb根据IP获得区域
https://www.ipip.net/download.html https://github.com/17mon/csharp IpAndPositionHelper public class ...
- es6 generator 基础知识
1.定义和使用 function *gen() { return 'first generator'; } // 有点类似类的实例化过程 let generatorResult = gen() // ...
- 集群瓶颈:磁盘IO必读
首先需要知道什么是IO: IO是输入输出接口阅读本文章可以带着下面问题1.集群的瓶颈为什么IO?2.你对IO了解多少? 这里面只说个人观点:当我们面临集群作战的时候,我们所希望的是即读即得.可是面对大 ...
- STORM在线业务实践-集群空闲CPU飙高问题排查(转)
最近将公司的在线业务迁移到Storm集群上,上线后遇到低峰期CPU耗费严重的情况.在解决问题的过程中深入了解了storm的内部实现原理,并且解决了一个storm0.9-0.10版本一直存在的严重bug ...
- TRIZ系列-创新原理-9~11-预先反作用原理、预处理原理、预先防范原理
一.预先反作用原理表述例如以下: 1)预先给物体施加反作用,以补偿过量的或者不想要的压力. 假设知道系统在执行过程中,会有不利的或者有害的作用(负面作用)产生,则能够预先採取一定的措施来抵消.控制这样 ...