Qt源码学习之路(2) QCoreApplication(1)
QCoreApplication最重要的函数便是exec(),我们便从这个函数开始分析QCoreApplication都干了什么。
先列出exec()函数的源码
static int exec();//函数声明
/*!
Enters the main event loop and waits until exit() is called.
Returns the value that was set to exit() (which is 0 if exit() is
called via quit()).
It is necessary to call this function to start event handling. The
main event loop receives events from the window system and
dispatches these to the application widgets.
To make your application perform idle processing (by executing a
special function whenever there are no pending events), use a
QTimer with 0 timeout. More advanced idle processing schemes can
be achieved using processEvents().
We recommend that you connect clean-up code to the
\l{QCoreApplication::}{aboutToQuit()} signal, instead of putting it in
your application's \c{main()} function because on some platforms the
exec() call may not return. For example, on Windows
when the user logs off, the system terminates the process after Qt
closes all top-level windows. Hence, there is no guarantee that the
application will have time to exit its event loop and execute code at
the end of the \c{main()} function after the exec()
call.
\sa quit(), exit(), processEvents(), QApplication::exec()
*/
int QCoreApplication::exec()//函数定义
{
if (!QCoreApplicationPrivate::checkInstance("exec"))
return -;
QThreadData *threadData = self->d_func()->threadData;
if (threadData != QThreadData::current()) {
qWarning("%s::exec: Must be called from the main thread", self->metaObject()->className());
return -;
}
if (!threadData->eventLoops.isEmpty()) {
qWarning("QCoreApplication::exec: The event loop is already running");
return -;
}
threadData->quitNow = false;
QEventLoop eventLoop;
self->d_func()->in_exec = true;
self->d_func()->aboutToQuitEmitted = false;
int returnCode = eventLoop.exec();
threadData->quitNow = false;
if (self) {
self->d_func()->in_exec = false;
if (!self->d_func()->aboutToQuitEmitted)
emit self->aboutToQuit(QPrivateSignal());
self->d_func()->aboutToQuitEmitted = true;
sendPostedEvents(, QEvent::DeferredDelete);
}
return returnCode;
}
我们先看函数声明,它是一个static函数这也就意味着我们在一个Qt进程中只能有一个QCoreApplication,exec()函数只需调用一次(猜想后续深入研究)
再看函数定义,在解析函数定义之前我们先看下函数的注释信息,这有助于我们去分析函数定义。
注释信息主要说了这个函数会开启主事件循环并且进入阻塞状态,直到exit()函数被调用,返回值exit()函数设置的值。
所谓的事件循环其实就是信号槽机制的本质,只有开启事件循环之后,信号槽才能起作用。
注释最后说了我们的析构处理最好不要放在main函数中exec()调用之后执行,因为exec()有可能会不返回。它举了个例子,没有太看懂,它说当用户注销时,系统会先关闭Qt程序的顶级显示窗口,然后终止进程,这是不能保证exec()函数会有返回。我的看法是,它这个例子是说我们关机,强制注销电脑时,操作系统会先关掉我们程序的显示界面再强制终止程序的进程,这个时候exec()可能是没有返回的,一般我们程序都关掉了也不会有什么其他的处理了,当然如果你要是想在主线程注销时写日志的话可能就得按照它所说的去做了,将后续的处理函数与aboutToQuit()信号绑定,那么在将要关闭主事件循环时,它会发送这个信号来调用你的处理函数而不必去等待exec()的返回了。
接下来我们继续分析exec()函数的定义。
函数开头做的一件事是去检查QCoreApplication的对象是否存在,如果不存在则返回。
QThreadData是存储线程数据信息的一个类,有点像是线程的句柄,但是它里面存储的信息要比句柄多。判断当前线程是否是主线程,如果不是则返回同时提醒用户。
也就是说我们的QCoreApplication的定义必须是在main()函数所在的主线程中。
然后判断主事件循环是否已经开启了,如果已开启则返回。
接下来就是一些数据信息的赋值了,将线程的退出信息quitNow置为false,将exec()是否已经调用置为true,将我们前面说过的aboutToQuit信号是否发射置为false
然后便是定义一个EventLoop对象,它是主事件循环对象,调用eventLoop.exec()开启主事件循环,并进入阻塞状态等待返回。
当主事件循环关闭并返回之后,则发送aboutToQuit信号,然后exec()函数结束并返回从主事件循环那儿得到的返回值。整个exec()的完整流程便结束了。
这篇就分析到这里,下篇继续分析QEventLoop的exec()都干了什么具体的东西
Qt源码学习之路(2) QCoreApplication(1)的更多相关文章
- spring源码学习之路---深入AOP(终)
作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 上一章和各位一起看了一下sp ...
- spring源码学习之路---IOC初探(二)
作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 上一章当中我没有提及具体的搭 ...
- Qt源码学习之信号槽
Qt源码版本 Qt 5.12.0 moc文件 Qt在编译之前会分析源文件,当发现包含了Q_OBJECT宏,则会生成另外一个标准的C++源文件(包含Q_OBJECT宏实现的代码,文件名为moc_+原文件 ...
- spring源码学习之路---AOP初探(六)
作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 最近工作很忙,但当初打算学习 ...
- spring源码学习之路---环境搭建(一)
作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 最近已经开始了spring源 ...
- spring源码学习之路---IOC实现原理(三)
作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 上一章我们已经初步认识了Be ...
- Java JDK1.8源码学习之路 2 String
写在最前 String 作为我们最常使用的一个Java类,注意,它是一个引用类型,不是基本类型,并且是一个不可变对象,一旦定义 不再改变 经常会定义一段代码: String temp = " ...
- Java JDK1.8源码学习之路 1 Object
写在最前 对于一个合格的后端程序员来说,现行的流行框架早已经能胜任基本的企业开发,Springboot 任何的框架都把重复的工作更佳简单/优化的解决掉,但是完全陷入在这样的温水里面, 好比温水煮青蛙, ...
- 走进Spring Boot源码学习之路和浅谈入门
Spring Boot浅聊入门 **本人博客网站 **IT小神 www.itxiaoshen.com Spring Boot官网地址:https://spring.io/projects/spring ...
随机推荐
- 通过cmd命令将jar放到maven仓库
如:将jar包直接拷贝到mave仓库的文件夹是不能直接使用的,需要通过cmd命令将jar生产maven可用的 mvn install:install-file -Dfile=iTextAsian-1. ...
- 【CMDB】API传输验证
客户端向服务器发送请求时,在请求头添加自定义的字符串 客户端的加密方式 1.对key+time进行md5加密 2.发送的时候的格式为md5_key|time,将时间也发送过去 服务器端验证 1.获取加 ...
- etcd数据备份和恢复--转发
对于etcd api v3数据备份与恢复方法 # export ETCDCTL_API=3 # etcdctl --endpoints localhost:2379 snapshot save sna ...
- Spring Cloud Ribbon负载均衡(快速搭建)
Spring Cloud Ribbon 是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现.通过 Spring Cloud 的封装, 可以让我们轻松地将面向服务的 ...
- 微服务:springboot与swagger2的集成
现在测试都提倡自动化测试,那我们作为后台的开发人员,也得进步下啊,以前用postman来测试后台接口,那个麻烦啊,一个字母输错就导致测试失败,现在swagger的出现可谓是拯救了这些开发人员,便捷之处 ...
- spring的声明式事务和编程式事务
事务管理对于企业应用来说是至关重要的,当出现异常情况时,它可以保证数据的一致性. Spring事务管理的两种方式 1.编程式事务 使用Transaction Ttempleate或者直接使用底层的Pl ...
- java处理异常的机制关键字为throw和throws
在异常处理的过程中,throws和throw的区别是? throws:是在方法上对一个方法进行声明,而不进行处理,而是向上传,谁调用谁处理. throw:是在具体的抛出一个异常类型. throws的栗 ...
- 6、Python基础语法
一.Python输出 print是python输出的关键字,默认是输出内容后换行. 如果不想换行,需要在变量末尾加上 end="" . a = 'hello' b = 'world ...
- Spark 缓存机制
Spark中的缓存机制:避免spark每次都重算RDD以及它的所有依赖,cache().persist(). checkpoint(). 1.cache():会被重复使用,但是不能太大的RDD,将其c ...
- Redis 高可用架构设计(转载)
转载自:https://mp.weixin.qq.com/s?__biz=MzA3NDcyMTQyNQ==&mid=2649263292&idx=1&sn=b170390684 ...