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 ...
随机推荐
- WPF应用打包流程
1,安装工程模板插件Microsoft Visual Studio Installer Projects https://marketplace.visualstudio.com/items?item ...
- mysql高级用法(1)- mariadb的主从搭建
Mariadb介绍: mariadb是mysql的一个分支,需要进一步了解的参考:https://mariadb.org/ 安装参考教程:window版安装:Mariadb 介绍 1 (安装) lin ...
- Centos7安装DockerCE
1. 说明 以下使用的系统为centos7,64位,镜像为CentOS-7-x86_64-Minimal-1804,所有操作以root用户操作 2. 安装Docker官方源 2.1 安装yum工具集 ...
- HDU1213通畅工程-并查集求解
并查集的经典题目. 并查集.经典题目是HDU1232通畅工程. 题目描述: 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府"畅通工程"的目标 ...
- 四、Linux_用户切换
四.用户切换 # 切换用户的命令为: su username # 从普通用户切换到root用户,还可以使用命令: sudo su
- lvm逻辑卷扩容报错解决
报错: [root@centos21 space]# resize2fs /dev/centos/root resize2fs (-Dec-) resize2fs: Bad magic number ...
- 嵌入式Linux框架的理解
从事嵌入式linux工作也几年了,如果算上大学期间的自学,那么也算是个工程师了.期间写过底层bootloader.内核的驱动和上层应用程序.对于芯片内部的模块也在大学时候用fpga的verilog玩过 ...
- Hbase的表结构中rowkey的设计---避免热点问题
热点问题 hbase 中的行是以 rowkey 的字典序排序的,这种设计优化了scan 操作,可以将相关的 行 以及会被一起读取的行 存取在临近位置,便于 scan . 然而,糟糕的 rowkey 设 ...
- Python 爬虫js加密破解(三) 百度翻译 sign
第一步: 模拟抓包分析加密参数 第二步: 找到加密字段 调试出来的sign和抓取得到的数据一致,都是 275626.55195 第三部: 分析js加密方法 第四部:运行js代码: 仅供交流学习使用
- js插件---webuploader 使用(lavarel中使用)
js插件---webuploader 使用(lavarel中使用) 一.总结 一句话总结: 多去看几个具体使用的实例,很多blog教程都有坑,多看几个交叉印证可以没那么多坑 1.webuploader ...