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 ...
随机推荐
- jQuery知识梳理20190817
目录 jQuery知识梳理20190817 1. jQuery的特征 2. jQuery的两把利器 2.1 jQuery核心函数 2.2 jQuery核心对象 3. jQuery核心函数详解 4. j ...
- python模块之json pickle
1.json模块 功能:将其他形式的数据类型转化为json字符串类型,将json字符串转化为其他对应的数据类型 方法:json.dumps() 作用:将所有单引号变成双引号:将所有数据类型变成字符串 ...
- Python,for循环小例子--99乘法表
一.99乘法表 for i in range(1, 10): for j in range(1, i + 1): print('%sx%s=%s ' % (j, i, j * i), end='') ...
- Docker存储卷篇
Docker存储卷篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.写时复制(COW)机制 所谓写时复制的效果如上图所示: Docker镜像由多个只读层叠加而成,启动容器 ...
- 第五次作业——Alpha项目测试
第五次作业——Alpha项目测试 格式描述: 这个作业属于哪个课程 2019秋软工17级系统分析与设计 这个作业要求在哪里 作业要求 团队名称 杨荣模杰和他的佶祥虎 这个作业的目标 测试其他组项目并写 ...
- Django项目中使用qq第三方登录。
使用qq登录的前提是已经在qq互联官网创建网站应用并获取到QQ互联中网站应用的APP ID和APP KEY 1,建路由 # qq登录 path('loginQq/',qq.loginQq,name=' ...
- 实用Golang库
框架: 1. Golang轻量级并发服务器框架: zinx / https://www.jianshu.com/p/23d07c0a28e52. 国内谢大牛模仿django制作的重框架: beego3 ...
- 五大开源 Web 代理服务器横评:Squid、Privoxy、Varnish、Polipo、Tinyproxy
https://linux.cn/article-7119-1.html Web 代理软件转发 HTTP 请求时并不会改变数据流量.它们可以配置成透明代理,而无需客户端配置.它们还可以作为反向代理放在 ...
- 学习Spring-Data-Jpa(十三)---动态查询接口JpaSpecificationExecutor
1.JpaSpecificationExecutor JPA2引入了一个criteria API,我们可以使用它以编程的形式构建查询.通过编写criteria,动态生成query语句.JpaSpeci ...
- LeetCode 1026. Maximum Difference Between Node and Ancestor
原题链接在这里:https://leetcode.com/problems/maximum-difference-between-node-and-ancestor/ 题目: Given the ro ...