`
gaofen100
  • 浏览: 1243342 次
文章分类
社区版块
存档分类
最新评论

Qt源码学习(从Win32到Qt)

 
阅读更多

本文以一个Win32的helloworld程序开篇,

  • 程序入口WinMain

  • 注册窗口类别
  • 建立窗口,在屏幕上显示
  • 进入事件循环,不断从事件队列中取出消息来处理

而后尝试解释前述各部分分别隐藏在Qt何处:

main()

程序入口

Qt提供一个WinMain来调用main

QWidget::show()

注册窗口类别

第一次使用时会注册类别

显示窗体

和hide、setHidden都是setVisble的马甲

QApplication::exec()

进入事件循环

核心是 QEventDispatcherWin32

声明,我对Win32编程不了解,本文只是Qt学习过程中的学习笔记,本文提到内容以及用词描述可能会不太准确。

一个简单的Win32程序

这是Win32编程的一个hello world程序:

  • 包含头文件,定义入口函数WinMain

  • 创建窗口类别(注意里面的WndProc是我们后面定义的回调函数),并注册窗口类别

  • 创建窗体,并显示与更新窗体

  • 启动事件循环

以上我们所讨论的都是必要的东西:注册窗口类别,建立窗口,在屏幕上显示窗口,进入事件循环,不断从事件队列中取出消息来处理。

实际的动作发生在消息处理函数中。该函数确定了在视窗的显示区域中显示些什么以及怎样响应用户的输入等。

  • 消息处理函数(回调函数)

用cl或gcc编译该程序:

考虑Qt?

既然是 hello world,也就基本是最简单的Win32程序了。但看着还是挺复杂,难怪大家都不怎么喜欢它。

Qt(或其他的图形库/框架)多简单啊,简单几行代码一个程序就出来了。可是... 简单的表象下面呢?我们如何把一个Windows下的 Qt 程序和上面的代码对应上?

  • 入口函数 WinMain

在Qt中我们只写main函数,不写WinMain,挺有意思哈,不过在Qt Windows下链接子系统与入口函数(终结版) 中我们已经详细讨论过这个问题了(简单地说:就是qtmain.lib或libqtmain.a提供了一个WinMain,它会调用我们的main)

  • 创建并注册窗体类别与创建并显示窗体部分

这个东西挺隐蔽的哈,当你对一个QWidget调用setVisble()或者它的众多马甲(比如show() )之一时,会执行这部分代码。源码位于qwidget_win.cpp 和 qapplication_win.cpp 文件中

  • 事件循环

这个循环体现在Qt中就是 QApplication::exec()。核心代码在qeventdispatcher_win.cpp 中。

注册窗体类别

当第一次调用setVisible()时,会进行窗口类别的创建,这最终会调用 qapplication_win.cpp 中的下面一个函数:

恩,和前面的比对一下,应该是一样的吧(注意这儿注册的回调函数函数名:QtWndProc)

附:调用关系:

  • QWidget::create()
  • ==>QWidgetPrivate::sys_create()

  • ==>qt_reg_winclass()

消息处理函数

接前面,不妨直接看看QtWndProc这个回调函数(在同一个文件内), 尽管我们都知道它里面是一个大大的switch语句,我还是贴一点它的代码出来:

注意:里面出现两处msg消息的过滤。可以对照 Manual 看。

  • QCoreApplication::filterEvent()
  • QWidget::winEvent()

接下来以whell事件为例,看一下Windows事件如果变成Qt中的事件,并进入Qt自身的消息循环的:

通过这个,我们看到:

  • 消息函数接受到的消息被封装成相应的QEvent,然后发送到Qt自身的事件循环中。
  • 我们可以看到接收事件的对象是如何一步一步被确定的。对于wheel事件:
    • 首先是光标下的widget(注意popup widget的处理)
    • 如果该widget不接受,则发送到有焦点的widget。
  • 通过这儿,我们应该容易理解QWheel中这句话的真实含义了:

事件循环

QDialog 模态对话框与事件循环 QEventLoop 的使用两例 等blog中,已经对此做过介绍:QApplication::exec()最终将(在一个while循环内)不断调用 qeventdispatcher_win.cpp 文件中的processEvents函数:

这个文件很复杂,此处只摘取了个人感兴趣的片段(其实是因为其他的大段我看不太懂):

  • 可以看到win32中熟悉的 PeekMessage、TranslateMessage、DispatchMessage

  • 注意用户输入事件和socket通知事件的处理(放入queued队列)
  • 注意此处也有一个 filterEvent,和QApplication提供的过滤器比较一下。发现谁更厉害没?

写到到这个地方,似乎从win32到Qt的对比分析已经做完了。恩,我也觉得差不多,只是...

对与 QEventDispatcherWin32 这个东西,我们还有很多话没说。它是事件循环的关键,而且它不止在主线程使用(我们肯定都知道QThread::exec())。

QEventDispatcherWin32补遗

QTimer源码分析(以Windows下实现为例) 我们提到了它和定时器Timer的密切关系,刚刚又提到它是事件循环的关键,还有一点似乎还需要提一下:

  • QApplication 初始化时创建该对象

  • 在构造函数中,它创建并注册了一个内部用的窗口类别,而后创建一个窗口。

其回调函数 qt_internal_proc 也在该文件内(略过)

  • 在创建内部窗口的同时,它还安装了一个钩子(Hook)

  • 在钩子的回调函数中,一些消息被PostMessage到上面提到的内部窗口中

总算大体上理了一遍,尽管很多东西还是不懂。有错误欢迎大家指出哈 dbzhang800 2011.04.28

写的途中发现一个技术大牛 tingsking18 写过这方面的东西了(链接附文后),不过我还是认为自己的更详细一点。

参考

分享到:
评论

相关推荐

    QT实现的模拟win+r窗口

    QT是一种跨平台的应用程序...通过这个项目,开发者可以学习到如何使用QT来创建具有交互性的GUI应用,理解信号与槽机制,以及如何处理用户输入和执行命令。这不仅是一个基础的GUI编程练习,也是深入理解QT框架的好起点。

    Win7-64-Qt5.6.1开发环境下载和安装

    1. **添加环境变量**:安装完成后,确保Qt的bin目录(通常在`C:\Qt\5.6\mingw53_64\bin`)添加到系统的PATH环境变量中。这将使得在任何目录下都可以运行Qt相关的命令。 2. **验证安装**:打开命令提示符,输入`...

    win10+Qt5.15.2+mingw81_64编译mysql8.0生成的驱动插件

    2. **获取源代码**:从Qt官方仓库或者第三方资源获取Qt的源代码,特别是sqldrivers模块,它包含了各种数据库驱动的源码。 3. **编译驱动插件**:使用qmake和mingw32-make命令来编译MySQL驱动插件。你需要指定正确的...

    Qt使用qbreakpad示例工程(win32,macos,linux).zip

    本文将详细介绍如何在Qt框架下利用qbreakpad库,实现Windows(Win32)、MacOS和Linux平台的跨平台异常捕获与分析。 首先,让我们了解核心组件——qbreakpad。qbreakpad是基于Google Breakpad的Qt接口,它允许开发者...

    qt-vlc源码和库和demo

    首先,`VLC-Qt_1.1.0_win32_mingw.7z`可能是VLC-Qt库的一个预编译版本,适用于Windows 32位系统,并且基于MinGW编译环境。VLC-Qt是VLC和Qt之间的桥梁,它提供了一系列的C++类和函数,使得在Qt应用中轻松集成VLC...

    Qt五子棋程序源码

    学习这个源码,你可以了解Qt的GUI设计、事件处理、多线程(如果涉及到AI的异步计算)、文件I/O(保存和加载游戏状态)以及简单的游戏算法。同时,对于想要提升C++和Qt编程能力的人来说,这是一个很好的实践项目。...

    远程桌面监控 源码QT

    "Win32"可能是指这个程序也支持32位Windows系统,或者包含了特定于32位Windows的代码或配置。 综上所述,这个项目是一个使用C++和Qt框架编写的远程桌面监控程序,具有实时监控、鼠标锁定和局域网自动发现等功能。其...

    Qt+Cutelyst学习笔记(二十七)win10+Qt5.15.2+qmake实现一个简单的RESTful服务器 示例源码

    Qt+Cutelyst学习笔记(二十七)win10+Qt5.15.2+qmake实现一个简单的RESTful服务器 示例源码 https://blog.csdn.net/aggs1990/article/details/124115368 CSDN审核可能较慢,如无法下载,可以过段时间再回来看下

    基于OpenCV和Qt实现的视频编辑器源码+项目说明.zip

    基于OpenCV和Qt实现的视频编辑器源码+项目说明.zip基于OpenCV和Qt实现的视频编辑器源码+项目说明.zip基于OpenCV和Qt实现的视频编辑器源码+项目说明.zip基于OpenCV和Qt实现的视频编辑器源码+项目说明.zip基于OpenCV和...

    Qt+Cutelyst学习笔记(十二)win10 + Qt5.15.2 使用视图和模板 示例源码

    Qt+Cutelyst学习笔记(十二)win10 + Qt5.15.2 使用视图和模板 示例源码 https://blog.csdn.net/aggs1990/article/details/123903752 CSDN审核可能较慢,如无法下载,可以过段时间再回来看下

    QT5Checker4Win.zip

    QT5Checker4Win.zip是一个包含Windows平台上用于获取硬件信息的源码项目的压缩包。这个项目主要基于QT5框架,适用于Windows 10 LTSB(长期服务分支)操作系统,并且已经过与QT5.5.9版本及Visual Studio 2017的兼容性...

    QT入门之qt软件安装指南

    此外,不要忘记选择你想开发的应用程序平台,比如Win32或x64。 3. **Qt版本管理**:如果你计划同时开发多个Qt项目,可能需要安装多个Qt版本。Qt安装器允许你管理这些版本,以便在不同项目间切换。 4. **模块选择**...

    Qt5.7+Opencv2.4.13 (win7 64位)

    1. **下载并解压OpenCV**:从官方网站下载对应版本的OpenCV源码或预编译包,然后解压至指定路径(例如:`D:\Program\Opencv2413-minGW53-32`)。 - 如果使用的是MinGW编译器,需要通过`cmake`工具对下载的OpenCV...

    QT+Basler相机SDK开发源码+详细说明文档

    QT+Basler相机SDK开发源码与详细说明文档是一份非常宝贵的资源,它结合了QT图形用户界面框架和Basler...通过学习和理解这份源码,开发者可以提升在QT和工业相机集成方面的技能,进一步优化图像处理流程,提高生产效率。

    Qt+Cutelyst学习笔记(二十三)win10+Qt5.15.2 添加认证 示例源码

    Qt+Cutelyst学习笔记(二十三)win10+Qt5.15.2 添加认证 示例源码 https://blog.csdn.net/aggs1990/article/details/123997789 CSDN审核可能较慢,如无法下载,可以过段时间再回来看下

    Qt开发软件数据获取助手源码

    通过学习和研究这个项目的源码,开发者可以深入了解如何在Qt环境中使用Windows API,以及如何构建一个数据获取工具。这有助于提升对Windows系统底层运作的理解,同时增强在Qt环境中进行复杂应用开发的能力。对于想要...

    qt-win-opensource-src-4.5.2

    2. **解压源代码**:将"qt-win-opensource-src-4.5.2"解压到本地目录。 3. **配置编译选项**:根据需求配置QT的编译选项,如是否编译示例程序、文档等。 4. **编译源码**:使用编译器编译QT源代码,生成库文件。 5. ...

    Qt笔记(十六)之鼠标 键盘事件 源码

    - 为了在win10环境下编译通过,确保你的项目配置正确地指定了mingw32编译器,并且包含了必要的Qt库和模块。 总的来说,理解和掌握Qt中的鼠标和键盘事件处理是构建交互式图形界面的关键步骤。通过实践和研究...

    Qt+Cutelyst学习笔记(二十八)win10+Qt5.15.2+qmake接收表单提交的文件 示例源码

    Qt+Cutelyst学习笔记(二十八)win10+Qt5.15.2+qmake接收表单提交的文件 示例源码 https://blog.csdn.net/aggs1990/article/details/124128783 CSDN审核可能较慢,如无法下载,可以过段时间再回来看下

Global site tag (gtag.js) - Google Analytics