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 ...
随机推荐
- Mac版StarUML破解方法
StarUML是用nodejs写的.确切的说是用Electron前端框架写的.新版本中所有的starUML源代码是通过asar工具打包而成.确切的代码位置在“%LOCALAPPDATA%\Progra ...
- scrapy 图片管道学习笔记
使用scrapy首先需要安装 python环境使用3.6 windows下激活进入python3.6环境 activate python36 mac下 mac@macdeMacBook-Pro:~$ ...
- Linux环境变量设置declare/typeset
形而上,质在内!形形色色,追寻本质! declare/typeset declare 或 typeset 是一样的功能,就是在宣告变数的属性 declare 后面并没有接任何参数,那么bash 就会主 ...
- 基于gtk的imshow:用stb_image读取图像并用gtk显示
在前面一篇,已经能够基于gtk读取图像并显示.更前面的一篇:基于GDI的imshow:使用stb_image读取图像并修正绘制,通过stb_image读取图像并通过GDI显示图像,实现了一个imsho ...
- ELK-Elasticsearch 基础使用
一.基本概念 1 Node 与 Cluster Elastic 本质上是一个分布式数据库,允许多台服务器协同工作,每台服务器可以运行多个 Elastic 实例.单个 Elastic 实例称为一个节点( ...
- springcloud中微服务的优雅停机(已验证)
大部分项目部署中,为了方便,可能都直接使用kill -9 服务的pid来停掉服务. 但是由于Eureka采用心跳的机制来上下线服务,会导致服务消费者调用此已经kill的服务提供者然后出错. 可以采用以 ...
- python正则表达式(1)--特殊字符
正则表达式—特殊表达式含义 正则表达式的字母和数字表示他们自身,但多数字母和数字前加一个反斜杠时会拥有不同的含义. 下面列出了正则表达式模式语法中的特殊元素. 1.普通字符集 1) \w ...
- Spark 基础 —— 创建 DataFrame 的三种方式
1.自定义 schema(Rdd[Row] => DataSet[Row]) import org.apache.spark.sql.types._ val peopleRDD = spark. ...
- 关于git clone远程仓库账户密码错误的问题
这两天刚使用coding和git,但是在我第一次克隆coding上的项目的时候,提示输入账户和密码,当时我不知道这个账户和密码是指的哪个,就随便输入了,然后提示错误,,,,,, 之后每次克隆的时候都提 ...
- MySQL命令操作(Linux平台)
Linux shell 批量创建数据库/表 Shell 脚本如下: # create database and table HOST='localhost' PORT='3306' USER='roo ...