版权声明

请尊重原创作品。转载请保持文章完整性,并以超链接形式注明原始作者“tingsking18”和主站点地址,方便其他朋友提问和指正。

QT源码解析(一) QT创建窗口程序、消息循环和WinMain函数

QT源码解析(二)深入剖析QT元对象系统和信号槽机制

QT源码解析(三)深入剖析QT元对象系统和信号槽机制(续)

QT源码解析(四)剖析Qt的事件机制原理

QT源码解析(五)QLibrary跨平台调用动态库的实现

QT源码解析(六)Qt信号槽机制与事件机制的联系

QT源码解析(七)Qt创建窗体的过程

QT源码解析(八)Qt是如何处理windows消息的

QT源码解析(九)解析QDateTime

使用QT也有一段时间了,有的时候需要跟踪代码到QT的源码中去查找问题。在这里我将记录一下我跟踪QT源码学习到的一些知识。

我的开发环境是VC6.0+QT4.3.3。QT已经不为VC6.0提供addin了,所以有的时候我也会使用EclipseCDT来编写代码,因为有了QT for Eclipse的plugin写代码会方便一些。

我们在学习QT的时候,接触的第一个程序就是下面的helloworld程序:

[cpp] view plain copy
  1. #include <QApplication>
  2. #include <QPushButton>
  3. int main(int argc, char *argv[])
  4. {
  5. QApplication app(argc, argv);
  6. QPushButton hello("Hello world!");
  7. hello.resize(100, 30);
  8. hello.show();
  9. return app.exec();
  10. }

这个程序的作用很多手册和文档都已经讲了,讲的也都很细致,非常不错。

但是喜欢钻研,深入的童鞋也许开始注意了int main(int argc, char *argv[]),这个main函数是标准的main函数,而windows应用程序的入口是winmain函数,而main函数是命令行程序的入口。win下窗口程序都有RegisterClass,和消息循环,QT是如何RegisterClass和创建消息循环的?

下面我们将来一起学习一下QT的源码来解释一下这个main函数和整个窗口程序的创建过程:

设置好路径后,我们先F10一下,看看这个程序到底是从哪里开始运行的。

程序跳到了/winmain/qtmain_win.cpp文件的WinMain函数中,再看这个文件上面的宏定义:#define main qMain

继续看:在WinMain函数中调用了我们自己定义的main函数:int result = main(argc, argv.data());

哇塞,原来如此啊。原来我们写的main函数是假的。哈哈。

再来看一下QT是如何创建窗体和消息循环的

首先我们来到QApplication的构造函数:

QApplication::QApplication(int &argc, char **argv, int _internal)
    : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient))
{ Q_D(QApplication); d->construct(); QApplicationPrivate::app_compile_version = _internal;}

很明显,首先调用的是QApplicationPrivate的构造函数。大家注意第三个参数:QApplication::Type type

这事Type类型的定义:enum Type { Tty, GuiClient, GuiServer };

下面是代码注释中对Type类型的解释:

/enum QApplication::Type

/value Tty a console application
    /value GuiClient a GUI client application
    /value GuiServer a GUI server application (for Qt for Embedded Linux)

当程序运行到hello.show()的时候调用了QWidgetPrivate::create_sys函数。

在这里我们看到调用了类似RegisterClass的函数:QString windowClassName = qt_reg_winclass(q);

这里的q是指向QWidget的指针(我们先忽略掉这里)。

以及包括后面的CreateWindow,ShowWindow等等我们熟悉的WindowsAPI函数

const QString qt_reg_winclass(QWidget *w) 函数的原型是在qapplication_win.cpp中定义的。我们转到qt_reg_winclass函数的实现中。我们就看到了windows的API函数RegisterClass和窗口消息处理函数:wc.lpfnWndProc        = (WNDPROC)QtWndProc;

我们看一下QtWndProc的实现,原来窗口消息都是在这里进行处理的啊!

至于最后一句app.exec(); 调用了QCoreApplication的Exec函数,在这个函数中我们看到了下面创建消息循环的代码

QEventLoop eventLoop;
    self->d_func()->in_exec = true;
    int returnCode = eventLoop.exec();

在QCoreApplication.cpp中的注释是这样解释的:

The application will enter
    the event loop when exec() is called. exit() will not return
    until the event loop exits, e.g., when quit() is called.

到这里,main和WinMain函数到底是怎么回事,以及QT是怎么创建窗口和消息循环的,我们已经非常清楚了。

QT源码解析(一) QT创建窗口程序、消息循环和WinMain函数相关推荐

  1. Qt源码解析之事件系统(一)

    Qt源码解析之事件系统 一.向事件循环里面添加事件 二.QThread里面的事件循环 一.向事件循环里面添加事件 [static] void QCoreApplication::postEvent(Q ...

  2. Qt源码解析-源码解析-QVideoWidget播放手机视频旋转问题

    Qt源码解析 索引 Qt源码解析-源码解析-QVideoWidget播放手机视频旋转问题 问题描述与复现 使用手机拍摄的视频是竖屏的,上传后,使用QVideoWidget播放,变成横屏. 总结,可以让 ...

  3. Qt源码解析之QThread

    Qt源码解析之QThread 一.用法简介 二.源码分享 一.用法简介 1.工作类 class Worker : public QObject {Q_OBJECT public:explicit Wo ...

  4. Handler 源码解析——Handler的创建

    前言 Android 提供了Handler和Looper来来满足线程间的通信,而前面我们所说的IPC指的是进程间的通信.这是两个完全不同的概念. Handler先进先出原则,Looper类用来管理特定 ...

  5. win32创建窗口及其消息循环

    转自:http://anyzixin.blog.163.com/blog/static/365289122007103031657355/ http://anyzixin.blog.163.com/b ...

  6. Spring源码解析二之创建Bean(实例化)

    上一节我们分析到了createBean,而真正创建Bean的过程在doCreateBean过程,我们可以发现Spring的编码风格,do才是真正的过程,不带do的通常是在做在准备过程,并且我们跳过了一 ...

  7. 医疗小程序源码_不懂商城小程序源码,如何快速创建小程序商城?

    小程序在近来发展十分迅速,从微信小程序游戏出发,到现在渗透到各种功能类型,甚至已经扩展到了其他的应用程序上.那么如今很多的小程序商城应该怎么创建呢?不懂商城小程序源码也可以自己制作吗?当然可以,下面小 ...

  8. Redis源码解析:21sentinel(二)定期发送消息、检测主观下线

    六:定时发送消息 哨兵每隔一段时间,会向其所监控的所有实例发送一些命令,用于获取这些实例的状态.这些命令包括:"PING"."INFO"和"PUBLI ...

  9. 源码解析2-GUI-绘制引擎(QPainter源码分析 )

    Qt源码解析 索引 Qt图形用户界面 应用程序窗口 Qt GUI 模块中最重要的类是QGuiApplication和QWindow.想要在屏幕上显示内容的 Qt 应用程序需要使用这些.QGuiAppl ...

最新文章

  1. Heartbeats
  2. 砸钱抢人抢项目,腾讯字节血拼游戏
  3. python实现Linux命令wget
  4. 想了解推荐系统最新研究进展?请收好这16篇论文
  5. git for windows_干货分享 | 嵌入式必备技能之Git的使用
  6. eclipse中经常用到的快捷键
  7. 解惑烟草行业工控系统如何风险评估
  8. 64位 int 占几个字节_面试常考,项目易错,长文详解C/C++中的字节对齐
  9. socket连接时间太长受什么原因影响?_光纤收发器的六个指示灯都代表什么?
  10. Flutter基础—绘画效果之不透明度
  11. 如何清洗 Git Repo 代码仓库
  12. 算法与数据结构1800题 之线性表 (一)
  13. Android源码:1、如何下载源码详解(一)
  14. 我的团长我的团第四十集
  15. 网页设计css导航链接怎么做,如何用DIV+CSS制作导航条
  16. 顶级赛事!2021 CCF大数据与计算智能大赛重磅开赛!
  17. FFMPEG AvFilter使用实例(实现视频缩放,裁剪,水印等)
  18. liquidFill---实现柱状水滴图
  19. java 当前线程 等待_Java 多线程等待
  20. 3GPP TS 23501-g51 中英文对照 | 4.4.7 MSISDN-less MO SMS Service

热门文章

  1. HTML学习02之基础;元素;属性
  2. cd返回上一 git_PHP项目中应用CI/CD的碎碎恋!
  3. MySQL流程控制if、case、循环结构while的使用语法
  4. 跟踪(Tracking)资料汇总
  5. 《深入理解Java虚拟机》笔记4——类文件结构
  6. Log4j使用详解(log4j.XML格式)
  7. java实现条件编译
  8. AbstractQueuedSynchronizer 原理分析 - 独占/共享模式
  9. Android开发如何进阶?
  10. 神经网络-全连接层(1)