没有合适的资源?快使用搜索试试~ 我知道了~
首页Qt5学习之路2:兼顾Qt4与Qt5的全面升级
Qt5学习之路2:兼顾Qt4与Qt5的全面升级
需积分: 13 9 下载量 70 浏览量
更新于2024-07-21
收藏 4.44MB PDF 举报
"《Qt学习之路2》是一套针对有一定C++基础的学习者设计的Qt5教程,旨在帮助读者掌握Qt开发的基础知识和常用GUI组件。相较于最初的系列,该教程是在原作发表三年后,基于Qt技术的显著进步进行修订的。Qt5虽然即将发布,但考虑到Qt4的广泛应用和Qt5相对平稳的升级特性,作者决定兼顾两个版本,以满足不同阶段开发者的需求。 本次修订的核心原则保持原有的教学结构,包括基础知识如编程基础、GUI组件介绍和常用技术讲解,同时融入Qt4和Qt5的对比内容。由于作者对Qt有了更深的理解,将在教程中更全面地介绍Qt的优秀特性,如XML处理、数据库集成和网络编程,弥补了前作的不足。 尽管目标定位于入门教程,但作者也提到可能会包含一些关于Qt实现层面的内容,例如信号槽的内部机制。这部分内容虽然不是基础,但可能会涉及一定程度的高级主题,对读者的技术要求较高。然而,作者也表示对此还存在不确定性,因为深入理解底层实现通常需要投入较多的时间和精力。 《Qt学习之路2》旨在提供一个全面且实用的Qt学习路径,适合想要进入或进一步提升Qt技能的开发者,不论他们是对Qt4还是Qt5感兴趣。"
资源详情
资源推荐
![](https://csdnimg.cn/release/download_crawler_static/9301037/bg10.jpg)
57
58
return app.exec();
}
当我们运行上面的程序时,会看到终端输出 Receives Newspaper: Newspaper A 这样的字样。
下面我们来分析下自定义信号槽的代码。
这段代码放在了三个文件,分别是 newspaper.h,reader.h 和 main.cpp。为了减少文件数量,
可以把 newspaper.h 和 reader.h 都放在 main.cpp 的 main() 函数之前吗?答案是,可以,
但是需要有额外的操作。具体问题,我们在下面会详细说明。
首先看 Newspaper 这个类。这个类继承了 QObject 类。只有继承了 QObject 类的类,才具
有信号槽的能力。所以,为了使用信号槽,必须继承 QObject。凡是 QObject 类(不管是直接
子类还是间接子类),都应该在第一行代码写上 Q_OBJECT。不管是不是使用信号槽,都应该
添加这个宏。这个宏的展开将为我们的类提供信号槽机制、国际化机制以及 Qt 提供的不基于
C++ RTTI 的反射能力。因此,如果你觉得你的类不需要使用信号槽,就不添加这个宏,就是错
误的。其它很多操作都会依赖于这个宏。注意,这个宏将由 moc(我们会在后面章节中介绍 moc。
这里你可以将其理解为一种预处理器,是比 C++ 预处理器更早执行的预处理器。) 做特殊处
理,不仅仅是宏展开这么简单。moc 会读取标记了 Q_OBJECT 的头文件,生成以 moc_ 为前
缀的文件,比如 newspaper.h 将生成 moc_newspaper.h。你可以到构建目录查看这个文件,
看看到底增加了什么内容。注意,由于 moc 只处理头文件中的标记了 Q_OBJECT 的类声明,
不会处理 cpp 文件中的类似声明。因此,如果我们的 Newspaper 和 Reader 类位于 main.cpp
中,是无法得到 moc 的处理的。解决方法是,我们手动调用 moc 工具处理 main.cpp,并且
将 main.cpp 中的 include “newspaper.h” 改为 include “moc_newspaper.h” 就可以了。不过,
这是相当繁琐的步骤,为了避免这样修改,我们还是将其放在头文件中。许多初学者会遇到莫名
其妙的错误,一加上 Q_OBJECT 就出错,很大一部分是因为没有注意到这个宏应该放在头文件
中。
Newspaper 类的 public 和 private 代码块都比较简单,只不过它新加了一个 signals。signals
块所列出的,就是该类的信号。信号就是一个个的函数名,返回值是 void(因为无法获得信号
的返回值,所以也就无需返回任何值),参数是该类需要让外界知道的数据。信号作为函数名,
不需要在 cpp 函数中添加任何实现
(我们曾经说过,Qt 程序能够使用普通的 make 进行编译。
没有实现的函数名怎么会通过编译?原因还是在 moc,moc 会帮我们实现信号函数所需要的函
数体,所以说,moc 并不是单纯的将 Q_OBJECT 展开,而是做了很多额外的操作)
。
Newspaper 类的 send() 函数比较简单,只有一个语句 emit newPaper(m_name);。emit 是 Qt
对 C++ 的扩展,是一个关键字(其实也是一个宏)。emit 的含义是发出,也就是发出 newPaper()
信号。感兴趣的接收者会关注这个信号,可能还需要知道是哪份报纸发出的信号?所以,我们将
实际的报纸名字 m_name 当做参数传给这个信号。当接收者连接这个信号时,就可以通过槽函
数获得实际值。这样就完成了数据从发出者到接收者的一个转移。
Reader 类更简单。因为这个类需要接受信号,所以我们将其继承了 QObject,并且添加了
Q_OBJECT 宏。后面则是默认构造函数和一个普通的成员函数。Qt 5 中,任何成员函数、static
函数、全局函数和 Lambda 表达式都可以作为槽函数。与信号函数不同,槽函数必须自己完成
实现代码。槽函数就是普通的成员函数,因此也会受到 public、private 等访问控制符的影响。
(我们没有说信号也会受此影响,事实上,如果信号是 private 的,这个信号就不能在类的外面
连接,也就没有任何意义。)
main() 函数中,我们首先创建了 Newspaper 和 Reader 两个对象,然后使用
QObject::connect() 函数。这个函数我们上一节已经详细介绍过,这里应该能够看出这个连接的
![](https://csdnimg.cn/release/download_crawler_static/9301037/bg11.jpg)
含义。然后我们调用 Newspaper 的 send() 函数。这个函数只有一个语句:发出信号。由于我
们的连接,当这个信号发出时,自动调用 reader 的槽函数,打印出语句。
这样我们的示例程序讲解完毕。我们基于 Qt 的信号槽机制,不需要观察者的容器,不需要注
册对象,就实现了观察者模式。
下面总结一下自定义信号槽需要注意的事项:
发送者和接收者都需要是 QObject 的子类(当然,槽函数是全局函数、Lambda 表
达式等无需接收者的时候除外);
使用 signals 标记信号函数,信号是一个函数声明,返回 void,不需要实现函数代码;
槽函数是普通的成员函数,会受到 public、private、protected 的影响;
使用 emit 在恰当的位置发送信号;
使用 QObject::connect() 函数连接信号和槽。
Qt 4
下面给出 Qt 4 中相应的代码:
Language: C++ (Qt)
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//!!! Qt4
#include <QObject>
////////// newspaper.h
class Newspaper : public QObject
{
Q_OBJECT
public:
Newspaper(const QString & name) :
m_name(name)
{
}
void send() const
{
emit newPaper(m_name);
}
signals:
void newPaper(const QString &name) const;
private:
QString m_name;
};
////////// reader.h
#include <QObject>
![](https://csdnimg.cn/release/download_crawler_static/9301037/bg12.jpg)
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <QDebug>
class Reader : public QObject
{
Q_OBJECT
public:
Reader() {}
public slots:
void receiveNewspaper(const QString & name) const
{
qDebug() << "Receives Newspaper: " << name;
}
};
////////// main.cpp
#include <QCoreApplication>
#include "newspaper.h"
#include "reader.h"
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
Newspaper newspaper("Newspaper A");
Reader reader;
QObject::connect(&newspaper, SIGNAL(newPaper(QString)),
&reader, SLOT(receiveNewspaper(QString)));
newspaper.send();
return app.exec();
}
注意下 Qt 4 与 Qt 5 的区别。
Newspaper 类没有什么区别。
Reader 类,receiveNewspaper() 函数放在了 public slots 块中。在 Qt 4 中,槽函数必须放在
由 slots 修饰的代码块中,并且要使用访问控制符进行访问控制。其原则同其它函数一样:默认
是 private 的,如果要在外部访问,就应该是 public slots;如果只需要在子类访问,就应该是
protected slots。
main() 函数中,QObject::connect() 函数,第二、第四个参数需要使用 SIGNAL 和 SLOT 这
两个宏转换成字符串(具体事宜我们在上一节介绍过)。注意 SIGNAL 和 SLOT 的宏参数并不
是取函数指针,而是除去返回值的函数声明,并且 const 这种参数修饰符是忽略不计的。
![](https://csdnimg.cn/release/download_crawler_static/9301037/bg13.jpg)
Qt 学习之路 2(6):Qt 模块简介
作者: 豆子 日期: 2012 年 08 月 26 日 发表评论 (5) 查看评论
Qt 5 与 Qt 4 最大的一个区别之一是底层架构有了修改。Qt 5 引入了模块化的概念,将众多功
能细分到几个模块之中。Qt 4 也有模块的概念,但是是一种很粗的划分,而 Qt 5 则更加细化。
本节主要对 Qt 5 的模块进行一个简单的介绍,以便以后大家需要哪些功能的时候知道到哪个模
块去寻找。
Qt 5 模块分为 Essentials Modules 和 Add-on Modules 两部分。前者是基础模块,在所有平台
上都可用;后者是扩展模块,建立在基础模块的基础之上,在能够运行 Qt 的平台之上可以酌
情引入。
Qt 基础模块分为以下几个:
Qt Core,提供核心的非 GUI 功能,所有模块都需要这个模块。这个模块的类包括了
动画框架、定时器、各个容器类、时间日期类、事件、IO、JSON、插件机制、智能指
针、图形(矩形、路径等)、线程、XML 等。所有这些类都可以通过 <QtCore> 头
文件引入。
Qt Gui,提供 GUI 程序的基本功能,包括与窗口系统的集成、事件处理、OpenGL 和
OpenGL ES 集成、2D 图像、字体、拖放等。这些类一般由 Qt 用户界面类内部使用,
当然也可以用于访问底层的 OpenGL ES 图像 API。Qt Gui 模块提供的是所有图形用
户界面程序都需要的通用功能。
Qt Multimedia,提供视频、音频、收音机以及摄像头等功能。这些类可以通过
<QtMultimedia> 引入,而且需要在 pro 文件中添加 QT += multimedia。
Qt Network,提供跨平台的网络功能。这些类可以通过 <QtNetwork> 引入,而且
需要在 pro 文件中添加 QT += network。
Qt Qml,提供供 QML(一种脚本语言,也提供 JavaScript 的交互机制) 使用的 C++
API。这些类可以通过 <QtQml> 引入,而且需要在 pro 文件中添加 QT += qml。
Qt Quick,允许在 Qt/C++ 程序中嵌入 Qt Quick(一种基于 Qt 的高度动画的用户
界面,适合于移动平台开发)。这些类可以通过 <QtQuick> 引入,而且需要在 pro 文
件中添加 QT += quick。
Qt SQL,允许使用 SQL 访问数据库。这些类可以通过 <QtSql> 引入,而且需要在
pro 文件中添加 QT += sql。
Qt Test,提供 Qt 程序的单元测试功能。这些类可以通过 <QtTest> 引入,而且需
要在 pro 文件中添加 QT += testlib。
Qt Webkit,基于 WebKit2 的实现以及一套全新的 QML API(顺便说一下,Qt 4.8 附
带的是 QtWebkit 2.2)。
Qt 扩展模块则有更多的选择:
Qt 3D,提供声明式语法,在 Qt 程序中可以简单地嵌入 3D 图像。Qt 3D 为 Qt Quick
添加了 3D 内容渲染。Qt 3D 提供了 QML 和 C++ 两套 API,用于开发 3D 程序。
Qt Bluetooth,提供用于访问蓝牙无线设备的 C++ 和 QML API。
![](https://csdnimg.cn/release/download_crawler_static/9301037/bg14.jpg)
Qt Contacts,用于访问地址簿或者联系人数据库的 C++ 和 QML API。
Qt Concurrent,封装了底层线程技术的类库,方便开发多线程程序。
Qt D-Bus,这是一个仅供 Unix 平台使用的类库,用于利用 D-Bus 协议进行进程间
交互。
Qt Graphical Effects,提供一系列用于实现图像特效的类,比如模糊、锐化等。
Qt Image Formats,支持图片格式的一系列插件,包括 TIFF、MNG、TGA 和 WBMP。
Qt JS Backend,该模块没有公开的 API,是 V8 JavaScript 引擎的一个移植。这个
模块仅供 QtQml 模块内部使用。
Qt Location,提供定位机制、地图和导航技术、位置搜索等功能的 QML 和 C++ API。
Qt OpenGL,方便在 Qt 应用程序中使用 OpenGL。该模块仅仅为了程序从 Qt 4 移
植到 Qt 5 的方便才保留下来,如果你需要在新的 Qt 5 程序中使用 OpenGL 相关技
术,需要使用的是 QtGui 模块中的 QOpenGL。
Qt Organizer,使用 QML 和 C++ API 访问组织事件(organizer event)。organizer
API 是 Personal Information Management API 的一部分,用于访问 Calendar 信息。
通过 Organizer API 可以实现:从日历数据库访问日历时间、导入 iCalendar 事件或
者将自己的事件导出到 iCalendar。
Qt Print Support,提供对打印功能的支持。
Qt Publish and Subscribe,为应用程序提供对项目值的读取、导航、订阅等的功能。
Qt Quick 1,从 Qt 4 移植过来的 QtDeclarative 模块,用于提供与 Qt 4 的兼容。
如果你需要开发新的程序,需要使用 QtQuick 模块。
Qt Script,提供脚本化机制。这也是为提供与 Qt 4 的兼容性,如果要使用脚本化支
持,请使用 QtQml 模块的 QJS* 类。
Qt Script Tools,为使用了 Qt Script 模块的应用程序提供的额外的组件。
Qt Sensors,提供访问各类传感器的 QML 和 C++ 接口。
Qt Service Framework,提供客户端发现其他设备的服务。Qt Service Framework
为在不同平台上发现、实现和访问服务定义了一套统一的机制。
Qt SVG,提供渲染和创建 SVG 文件的功能。
Qt System Info,提供一套 API,用于发现系统相关的信息,比如电池使用量、锁
屏、硬件特性等。
Qt Tools,提供了 Qt 开发的方便工具,包括 Qt CLucene、Qt Designer、Qt Help 以
及 Qt UI Tools 。
Qt Versit,提供了对 Versit API 的支持。Versit API 是 Personal Information
Management API 的一部分,用于 QContacts 和 vCard 以及 QOrganizerItems 和
iCalendar 之间的相互转换。
Qt Wayland,仅用于 Linux 平台,用于替代 QWS,包括 Qt Compositor API(server)
和 Wayland 平台插件(clients)。
Qt WebKit,从 Qt 4 移植来的基于 WebKit1 和 QWidget 的 API。
Qt Widgets,使用 C++ 扩展的 Qt Gui 模块,提供了一些界面组件,比如按钮、单
选框等。
Qt XML,SAX 和 DOM 的 C++ 实现。该模块已经废除,请使用
QXmlStreamReader/Writer。
Qt XML Patterns,提供对 XPath、XQuery、XSLT 和 XML Schema 验证的支持。
剩余244页未读,继续阅读
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://profile-avatar.csdnimg.cn/default.jpg!1)
pangzengyao123
- 粉丝: 0
- 资源: 2
上传资源 快速赚钱
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助
![](https://csdnimg.cn/release/wenkucmsfe/public/img/voice.245cc511.png)
最新资源
- 构建Cadence PSpice仿真模型库教程
- VMware 10.0安装指南:步骤详解与网络、文件共享解决方案
- 中国互联网20周年必读:影响行业的100本经典书籍
- SQL Server 2000 Analysis Services的经典MDX查询示例
- VC6.0 MFC操作Excel教程:亲测Win7下的应用与保存技巧
- 使用Python NetworkX处理网络图
- 科技驱动:计算机控制技术的革新与应用
- MF-1型机器人硬件与robobasic编程详解
- ADC性能指标解析:超越位数、SNR和谐波
- 通用示波器改造为逻辑分析仪:0-1字符显示与电路设计
- C++实现TCP控制台客户端
- SOA架构下ESB在卷烟厂的信息整合与决策支持
- 三维人脸识别:技术进展与应用解析
- 单张人脸图像的眼镜边框自动去除方法
- C语言绘制图形:余弦曲线与正弦函数示例
- Matlab 文件操作入门:fopen、fclose、fprintf、fscanf 等函数使用详解
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
![](https://img-home.csdnimg.cn/images/20220527035711.png)
![](https://img-home.csdnimg.cn/images/20220527035711.png)
![](https://img-home.csdnimg.cn/images/20220527035111.png)
安全验证
文档复制为VIP权益,开通VIP直接复制
![](https://csdnimg.cn/release/wenkucmsfe/public/img/green-success.6a4acb44.png)