## 12.10 使用 Qt Creator 调试程序
Qt Creator 集成了强大的调试器,提供了丰富多样的调试功能和选项,足以满足开发者 的需要。
### 12.10.1 调试器引擎
Qt Creator 本身并没有调试器,它必须借助其它的调试器引擎,并为它们提供了一个图 形化的前端界面。表 12-7 示出了在所支持的平台上,Qt Creator 使用的调试器。
表 12-7 Qt Creator 使用的调试器引擎
| 平台 | 编译器 | 调试器引擎 |
| --- | --- | --- |
| Linux, Unixes, Mac OS | gcc | GNU Symbolic Debugger (gdb) |
| Windows/MinGW | gcc | GNU Symbolic Debugger (gdb) |
| Windows | Microsoft Visual C++ | Compiler Debugging Tools for Windows/Microsoft Console Debugger (CDB) |
在 Qt Creator 中,你可以使用调试器前端界面逐行单步或逐过程调试程序,设置断点 ,检查堆栈中的内容,查看局部或全局变量的值等等,这些和我们常见的调试器提供的功能并无二致。而上述的原生信息,Qt Creator 会以清晰、简明的方式展现给程序员,这将使得原 本令人生畏的调试工作变得简单而有趣。
除了像堆栈查看器、局部变量和观察器、寄存器查看器等这些主流 IDE 都会提供的功能 外,Qt Creator 还提供了许多的功能以帮助开发者提高效率。由于调试器前端对 Qt 的内部 机制了如指掌,所以当程序出现问题时,它能够明晰描述症状。
表 12-8 示出了这些调试器引擎在单独安装时的一些需要注意的事项。
表 12-8 调试器引擎的相关信息
| 调试器引擎 | 注意事项 |
| --- | --- |
| GDB(X11 平台) | 需要 GDB6.8 或以上版本 |
| GDB 或 CDB | 可以从 Microsoft Developer Network 上自由下载 CDB,版本 6.10 以上,注意区分 32 位和 64 位版;(Windows 平台) 如果在 Windows 上使用 SDK 方式安装 Qt4 开源版,那么仍将使用 GDB 作为调试器引擎;如果使用 Microsoft Visual C++的编译器编译安装 Qt Creator,那么将使用 CDB 作为调试器引擎,并且默认情 况下,Qt Creator 将会检查%ProgramFiles%\Debugging Tools for Windows 这个路径下是否包含了所有需要的 调试器引擎的头文件。 |
### 12.10.2 与调试器交互
在 Debug 模式下时,Qt Creator 提供了许多的锚接窗口来辅助开发者与程序进行交互 。 常见的一些被设置为缺省可见的,不常使用的则缺省被隐藏。你可以依次点击【Debug】 →【View】来配置它们的显隐。
![](https://box.kancloud.cn/2016-01-22_56a1a160d4211.png)
图 12-41 设置常见辅助视图的显隐
如图 12-41 所示,你可以通过点击【Locked】菜单项来锁住或解锁你的锚接窗口的布局 , 就像设置这些锚接窗口的显隐一样。你的锚接窗口的位置将被 Qt Creator“记住”,下次启 动时它将根据上次的记忆来布局。
### 12.10.3 断点
你可以在断点视图( Breakpoints view )中查看断点。无论你的程序是否在运行和 调试中,断点视图都是默认并且随时可见的 。如图 12-42 所示,你可以在【Breakpoints】视图中查看断点设置的情况。图 12-43 显示了详细的断点信息。
![](https://box.kancloud.cn/2016-01-22_56a1a1610e3d4.png)
图 12-42 在【Breakpoints】视图中查看断点
![](https://box.kancloud.cn/2016-01-22_56a1a1612cd12.png)
图 12-43 断点的详细信息
所谓断点,就是由程序开发者设定的一系列条件 ,但程序以调试方式运行时,一旦符合 引发断点的“条件”,程序便中断执行,此后程序开发者便可以检视程序在运行时的状态 ,继 而控制程序的运行,直至找出问题所在。
在 Qt Creator 中,我们通常可以把断点与源代码文件或者其中的某一行关联起来,也 可以把它放在某个方法的起始处(通常指定义处 )。下面是设置断点的具体“规则”:
+ 在某一行代码设置断点--在代码行行号的左边缘处点击鼠标左键或者按下 F9 键(在 Mac OS X 系统中是 F8 键)
+ 在某一个函数处设置断点—依次点击菜单【Debug】 ->【Set Breakpoint at Function... 】,在其中输入函数的名字
你可以这样去掉一个断点:
+ 在代码编辑器内断点标识处用鼠标左键再次点击
+ 在断点视图中选中某个断点,并按下 Delete 键
+ 在断点视图内点击鼠标右键,在弹出的上下文窗口中选择 【Delete Breakpoint】 小贴士:断点可以在任意时刻设置-在程序开始调试之前和正在调试之时均可。断点的设置 也会作为一部分被当前的会话所保存。
### 12.10.4 程序的调试运行
要在调试模式下启动运行一个 Qt 应用程序,你可以依次点击菜单项【Debug】 →【Start Debugging】,或者按下 F5 键即可。Qt Creator 将检查程序代码或设置是否有更新,并在必要时重新编译项目,然后调试器将接管并启动程序的运行。
提示:Qt 应用程序在调试模式下启动运行时,往往需要一段时间,从几秒到若干分钟 不等,这取决于你的机器的配置以及程序的复杂程度(比如应用了 QtWebKit 模块的程序可能 要多花费一些时间)。
当程序调试运行未遇到断点时,它与直接运行状态并无区别。开发者可以依次点击菜单 项【Debug】 →【Interrupt】或者直接按下如图所示的调试器状态栏上的 【Interrupt】按 钮来中断程序的运行,这与程序在运行时遇到断点而停下来的效果是一样的 ,如图 12-44 所 示。
![](https://box.kancloud.cn/2016-01-22_56a1a1613e2a3.png)
图 12-44 调试器状态栏上的【Interrupt】按钮
当程序中断时,Qt Creator 将做如下的事情:
+ 获得程序中断处在堆栈中的地址
+ 获得局部变量的值
+ 检视并更新观察器(Watchers)视图内容
更新 Registers 、Modules 以及 Disassembler 视图 这时我们可以在 Debugger 视图中检视到程序更为详细的状态。
要结束调试状态,可以按下 Shift+F5 键。按下 F10 键可以进入逐行调试状态,按下 F11 键进入逐过程调试状态,按下 F5 键可以使程序运行到下一个断点处,如果后面没有断点了, 程序将完整的运行起来,这种情况仍然是在调试状态下的运行。
### 12.10.5 堆栈视图(Stack View)
当被调试的程序在断点处中断时,Qt Creator 将在堆栈视图中显示出程序到达断点处之 前所经历的那些函数。这些函数对应到被称作是“堆栈框架节点”,每一个节点对应一个函数。 如图 12-45 所示,Qt Creator 显示了这些函数所在的文件名、在源代码里面的行号。
![](https://box.kancloud.cn/2016-01-22_56a1a1614ab14.png)
图 12-45 堆栈视图
有些情况下,不是所有的框架节点都能够准确的对应到源代码中的一个位置 ,因而也就 没有相应的调试信息,这些调试框架将被灰色显示。
当你在堆栈视图里面显示的某一行处使用鼠标左键双击时 ,代码编辑器将跳转至相应的 代码行,Qt Creator 将更新局部变量和观察器视图,就像把断点设置到这个地方而程序正好 在这里中断时的情形一样。
### 12.10.6 线程视图(Thread View)
当我们调试一个多线程应用程序时,如图 12-46 所示,线程视图(thread view)和调 试器状态栏上的”Thread”组合框(见图 12-47)被用来在不同线程间切换,这时堆栈视图(stack view)也将会随着做出相应的调整。
![](https://box.kancloud.cn/2016-01-22_56a1a1616aa58.png)
图 12-46 线程视图
![](https://box.kancloud.cn/2016-01-22_56a1a1617b074.png)
图 12-47 调试器状态栏上的 Thread 组合框
### 12.10.7 局部变量和观察器视图(Locals and Watchers View)
当程序在调试器的控制下中断时,Qt Creator 将取得堆栈里面的最上层框架节点的相关 信息并把它们显示在局部变量和观察器视图里面。
局部变量和观察器视图通常由一个树形结构组成 ,里面有许多的一级节点,第二级节点 等等层次的数据,比如数据结构和类等信息就不是显示在第一级节点里面的。要查看更为详 细的信息,可以逐级点开这些节点前面的 “+”号。
你也可以在局部变量和观察器中更改变量的内容(比如常见的 int 和 float 值),以界 定你想确定的变量值的限值。这可以通过双击 ”Value”栏,并在可编辑区填入你的新的取 值,然后按下回车键(Enter 或 Return 键),之后再接着调试程序。
小贴士:你对观察器里面项目的设置将被保存到这次会话里面 ,下次打开对话时,这些设置 仍然有效。
### 12.10.8 模块视图(Modules Views)
默认情况下,模块视图也是不显示的。它的主要作用是使开发者了解程序中用到了那些模块,严格意义上来说,它不应该是在调试模式下才有的功能。一个常见的模块视图如图12-48 所示。
![](https://box.kancloud.cn/2016-01-22_56a1a16188bf7.png)
图 12-48 模块视图
### 12.10.9 反汇编和视图(Disassembler View)和寄存器视图(Registers View)
默认情况下,反汇编视图和寄存器视图是隐藏的。反汇编视图显示了断点处所在的函数的反汇编代码,如图 12-49 所示;寄存器视图显示了当前 CPU 的寄存器的状态,如图 12-50所示,当你需要对程序的底层(与系统硬件接触)进行检视和控制时,这两个视图尤其有用。 当我们使用逐过程调试的方法时,经常会用到它们。
![](https://box.kancloud.cn/2016-01-22_56a1a1619be45.png)
图 12-49 反汇编视图
![](https://box.kancloud.cn/2016-01-22_56a1a161b218c.png)
图 12-50 寄存器视图
### 12.10.10 程序调试实例
在我们的这个 TextFinder 例子里面,我们要使用 QString 读取一个文本文件,然后再 用一个 QTextEdit 把它的内容显示出来。在其中我们定义了一个 QString 类型的变量 line, 然后在附近设置一个断点,用来查看 line 变量的内容,请大家跟着我的步骤进行调试。
![](https://box.kancloud.cn/2016-01-22_56a1a161c8462.png)
图 12-51 设置断点
首先是设置断点,如图 12-51 所示,将光标移动到选定的位置,按下 F9 键,或者在行号前点击鼠标左键完成断点的设置。然后按下 F5 键,启动调试。
如图 12-52 所示,在调试模式(Debug Mode)下,我们可以在断点视图(Breakpoints View)中查看已经设置的断点情况。要取消断点,可以再次点击 F9 键。
![](https://box.kancloud.cn/2016-01-22_56a1a161df929.png)
图 12-52 查看断点设置情况
可以在局部变量和观察器视图中查看变量的内容,如图 12-53 所示,显示了 line 等变 量的内容。
![](https://box.kancloud.cn/2016-01-22_56a1a161f2f69.png)
图 12-53 查看 line 变量的内容
下面是我们的程序中的槽函数 on_findButton_clicked()的代码,我们将修改代码中的 部分内容,形成一个小的逻辑错误,然后示范调试的步骤。原始正确的代码如下:
```
QString searchString = ui_lineEdit->text();
QTextDocument *document = ui_textEdit->document();
bool found = false;
if (isFirstTime == false)
document->undo();
if (searchString == "")
{
QMessageBox::information(this, tr("Empty Search Field"),
"The search field is empty. Please enter a word and click Find.");
}
else
{
QTextCursor highlightCursor(document);
QTextCursor cursor(document);
cursor.beginEditBlock();
QTextCharFormat plainFormat(highlightCursor.charFormat());
QTextCharFormat colorFormat = plainFormat;
colorFormat.setForeground(Qt::red);
while (!highlightCursor.isNull() && !highlightCursor.atEnd())
{
highlightCursor = document->find(searchString, highlightCursor,
QTextDocument::FindWholeWords);
if (!highlightCursor.isNull())
{
found = true;
highlightCursor.movePosition(QTextCursor::WordRight,
QTextCursor::KeepAnchor);
highlightCursor.mergeCharFormat(colorFormat);
}
}
cursor.endEditBlock();
isFirstTime = false;
if (found == false)
{
QMessageBox::information(this, tr("Word Not Found"),
"Sorry, the word cannot be found.");
}
}
```
我们将第 6 行改为:
```
if (searchString != "")
```
大家注意,改动之处是把 比较运算符==变成了!=,这时运行程序,无论你输入任何有效的字符,程序的运行结果总是与你的预期相反。那么就需要设置断点,调试程序了。在第 一行处按下 F9 键,然后按下 F5 键开始调试,如图 12-54 所示,使用鼠标点击调试器工具栏 上的常用按钮或者按下对应的快捷键,执行逐行调试或逐过程调试均可,如图 11-54 所示。 程序单步执行到第 6 行时,你将会发现这个逻辑错误。把它更正过来,再次调试程序即可 。
![](https://box.kancloud.cn/2016-01-22_56a1a1621647b.png)
图 12-54 调试器工具栏
至此,关于 Qt Creator 的使用的介绍就结束了。要想掌握好 Qt Creator,使之成为你 的左膀右臂,就需要多实践,多总结。
- 第 1 章 走近 Qt
- 1.1 Qt 简介
- 1.2 Qt 纪事概览
- 1.3 Qt 套件的组成(以 Qt4.5 为准)
- 1.4 Qt 的授权
- 1.5 Qt 的产品
- 1.6 Qt 的服务与支持
- 1.7 Qt 的最新进展
- 1.8为什么选择 Qt
- 1.9 问题与解答
- 1.10 总结与提高
- 第 2 章 Qt 的安装与配置
- 2.1 获取 Qt
- 2.2 协议说明
- 2.3 安装 Qt
- 2.4 配置 Qt4 环境
- 2.5 问题与解答
- 2.6 总结与提高
- 第 3 章 Qt 编程基础
- 3.1 标准 C++精讲
- 3.2 Windows 编程基础
- 3.3 Linux 编程基础
- 3.4 Mac 编程基础
- 3.5 问题与解答
- 3.6 总结与提高
- 第 4 章 Qt 4 集成开发环境
- 4.1 常见的 Qt IDE
- 4.2 Qt Creator
- 4.3 Eclipse
- 4.5 问题与解答
- 4.6 总结与提高
- 第 5 章 使用 Qt 基本 GUI 工具
- 5.1 使用 Qt Designer 进行 GUI 设计
- 5.2 使用 Qt Assistant 获取在线文档与帮助
- 5.3 使用 Qt Demo 学习 Qt 应用程序开发
- 5.4 问题与解答
- 5.5 总结与提高
- 第 6 章 Qt 4 程序开发方法和流程
- 6.1 开发方法
- 6.2 Hello Qt
- 6.3 几个重要的知识点
- 6.4 问题与解答
- 6.5 总结与提高
- 第 7 章 对话框
- 7.1 QDialog 类
- 7.2 子类化 QDialog
- 7.3 快速设计对话框
- 7.4 常见内建(built in)对话框的使用
- 7.5 模态对话框与非模态对话框
- 7.6 问题与解答
- 7.7 总结与提高
- 第 8 章 主窗口
- 8.1 主窗口框架
- 8.2 创建主窗口的方法和流程
- 8.3 代码创建主窗口
- 8.4 使用 Qt Designer 创建主窗口
- 8.5 中心窗口部件专题
- 8.6 Qt4 资源系统专题
- 8.7 锚接窗口
- 8.8 多文档
- 8.9 问题与解答
- 8.10 总结与提高
- 第 9 章 Qt 样式表与应用程序观感
- 9.1 应用程序的观感
- 9.2 QStyle 类的使用
- 9.3 样式表概述
- 9.4 使用样式表
- 9.5 问题与解答
- 9.6 总结与提高
- 第 10 章 在程序中使用.ui 文件
- 10.1 uic 的使用
- 10.2 Ui_YourFormName.h 文件的组成
- 10.3 编译时加入处理.ui 文件的方法
- 10.4 运行时加入处理.ui 文件的方法
- 10.5 信号与槽的自动连接
- 10.6 问题与解答
- 10.7 总结与提高 本章主要讲解了以下内容:
- 第 11 章 布局管理
- 11.1 基本概念和方法
- 11.2在 Qt Designer 中使用布局
- 11.3 基本布局实践
- 11.4 堆栈布局
- 11.5 分裂器布局
- 11.6 自定义布局管理器
- 11.7 布局管理经验总结
- 11.8 问题与解答
- 11.9 总结与提高
- 第 12 章 使用 Qt Creator
- 12.1 Qt Creator 概览
- 12.2 Qt Creator 的组成
- 12.3 快捷键和常用技巧
- 12.4 Qt Creator 构建系统的设置
- 12.5 处理项目间依赖关系( Dependencies )
- 12.6 Qt 多版本共存时的管理
- 12.7 使用定位器在代码间快速导航
- 12.8 如何创建一个项目
- 12.9 实例讲解
- 12.10 使用 Qt Creator 调试程序
- 12.11 问题与解答
- 12.12 总结与提高
- 第 13 章 Qt 核心机制与原理
- 13.1 Qt 对标准 C++的扩展
- 13.2 信号与槽
- 13.3 元对象系统
- 13.4 Qt 的架构
- 13.5 Qt 的事件模型
- 13.6 构建 Qt 应用程序
- 13.7 总结与提高
- 附录 A qmake 使用指南
- A.1 qmake 简介
- A.2 使用 qmake
- 附录 B make 命令
- B.1 命令解释
- B.2 使用 make 自动构建
- 附录 C Qt 资源
- C.1Qt 官方资源
- C.2 Qt 开发社区