引言
Qt6 是一款强大的跨平台应用程序开发框架,支持多种编程语言,最常用的是C++。Qt6带来了许多改进和新功能,包括对C++17的支持、增强的QML和UI技术、新的图形架构,以及构建系统方面的革新。本文将指导你如何在Windows平台上下载和安装Qt6,以便开始你的开发之旅。
还在使用Qt5?是时候升级使用Qt6了。Qt5的最后一个长期支持版本,支持至 2025 年。Qt6开始已经不支持Win7了,而且Win10也只支持64位,不支持32位。
官方称 Qt 6 的任务是使 Qt 成为未来的生产力平台。作为 Qt 的主要版本,Qt 6.0 是 Qt 5 系列的延续,提供了更高的自由度,以实现新功能。
Qt 6中的新功能
Qt6的一些改进:
在 Qt 6 中加入了一个与 C++ 17 兼容的编译器,以便在开发 Qt 时使用更现代的 C++ 语言构造,并允许在 API方面进行集成。
作为 Qt 最核心部分的模块,Qt Core 本次更新遍历了许多领域并进行了改进,以下是一些最重要的变化:
新的属性和绑定系统:该系统现在带来了绑定的概念,这使得 QML 在 C++ 的 Qt 5 中取得了巨大的成功。字符串和 Unicode:官方从 Qt 5 开始将 Qt 与 Unicode 完全对齐,但是 Qt 6 中还有一些问题需要整理解决。更多详细信息将在稍后的单独博客中发布。 QList 是一个在 Qt 5 中经常被批评的类,因为它是堆分配存储在其中的对象的对象,该对象大于指针,从而给堆分配方法带来压力。在 Qt 6 中对此进行了更改,并将 QList 和 QVector 统一为一个类。有关详细信息,请参见 Qt 6 中有关 QList 的博客文章。QMetaType 和 QVariant 是 Qt 的元对象系统如何工作的基础。没有 QMetaType,就不可能有信号和插槽,并且动态调用需要 QVariant。这两个类在 Qt 6 中被几乎完全的重写。
Qt 的其他与图形无关的部分也发生了很大的变化。例如,Qt Concurrent 也经历了几乎完全的重写,并且现在比以往更加轻松地进行多线程应用程序的开发。Qt Network 也有许多清理和改进。
Qt 6 还对构建和分发 Qt 的方式进行了一些重大更改。值得一提的是,Qt 6 本身现在是使用 CMake 构建的。这也为使用 CMake 构建项目的所有用户带来了体验优化。官方将在 Qt 6 的生命周期内继续支持 qmake,因此老用户暂时无需对构建系统进行任何更改,但是官方建议所有新项目都使用 CMake。
Qt 支持的编译器介绍
Qt 支持多种编译器,包括 MinGW 和 Microsoft Visual C++ (MSVC) 工具链,在 Windows 平台上,这两种工具链各有优势和适用场景:
MinGW 工具链
- 开源和免费:MinGW 是基于 GNU 工具集的,包括 GCC 编译器,它是开源软件,不需要购买许可证。
- 轻量级:MinGW 只包含编译 Qt 所需的基本组件,没有集成开发环境 (IDE)。
- 跨平台:由于基于 GCC,MinGW 编译的代码更容易移植到其他平台,如 Linux 或 macOS。
- 静态链接:MinGW 允许静态链接到运行时库,这可以减少应用程序的外部依赖。
MSVC 工具链
- 集成开发环境:MSVC 通常与 Visual Studio IDE 结合使用,提供丰富的调试和开发工具。
- 性能优化:MSVC 编译器在某些情况下可以产生更优化的代码,尤其是在使用高级优化选项时。
- 动态链接:MSVC 编译的应用程序通常使用动态链接库 (DLLs),这可以减小应用程序的大小,便于更新和维护。
- 企业级支持:对于大型企业项目,MSVC 可能提供更好的技术支持和稳定性保证。
如果你仅在Windows上开发和部署应用程序,并且没有跨平台的需求,那么推荐使用MSVC(Microsoft Visual C++)工具链。一些组件如QWebEngineView只支持MSVC的工具链。选择MSVC工具链有以下优点:
-
最佳兼容性:MSVC是微软官方的编译器,与Windows操作系统及其API有最佳的兼容性。这意味着你的应用程序在Windows上的表现会更稳定,更少出现兼容性问题。
-
性能优化:MSVC编译器通常会产生性能更好的代码,尤其是在处理复杂的应用程序和大型项目时。微软对MSVC进行了大量的优化,以确保其生成的代码在Windows平台上运行效率最高。
-
集成开发环境:Visual Studio是Windows平台上最强大的集成开发环境之一,提供了丰富的工具和功能,如代码编辑、调试、性能分析、版本控制集成等。使用MSVC可以充分利用这些功能,提高开发效率。
-
第三方库支持:许多第三方库和工具在Windows上默认使用MSVC进行编译和发布。使用MSVC可以更方便地集成这些库,因为你可以直接使用预编译的二进制文件,而不需要自己编译。
msvc工具链下载安装
Microsoft C++ Build Tools,通过可编写脚本的独立安装程序提供 MSVC 工具集,无需使用 Visual Studio。 如果从命令行界面(例如,持续集成工作流中)生成面向 Windows 的 C++ 库和应用程序, 推荐使用此工具。
为什么使用msvc工具?因为Visual Studio太大啦,好几个G,且我已安装过一个版本了,不想再安装一个新版本了。编译NDD源码的需注意,QT框架需要5.11以上。c++编译器至少需要支持c++17以上才行。直接下载msvc工具链1G左右大小,且下载速度超快。
msvc工具链下载地址:
Microsoft C++ Build Tools - Visual Studio
安装这个需要注意的是,一定要勾选用于Windows的c++ Cmake工具这一项。默认包含msvc2022工具链,可选择安装msvc2019或2017。Qt6上推荐使用msvc2019。
Qt5升级到Qt6有哪些变化?
从Qt5升级到Qt6,你会发现有很多显著的变化和改进,这些变化主要集中在以下几个方面:
- C++17支持: Qt6要求编译器支持C++17标准,这使得Qt6能够利用现代C++特性,提高代码质量和性能。
- QML和UI技术的改进: Qt6引入了新一代的QML,提供了更多的功能和更好的性能。此外,UI渲染引擎得到了改进,以提高响应性和效率。
- 新的图形架构: Qt6支持多种图形API,如Vulkan和Metal,这为高性能图形应用提供了更好的支持,尤其是在跨平台场景下。
- 构建系统的改变: Qt6改用了CMake作为其构建系统,虽然它仍然支持qmake,但CMake的采用为项目提供了更广泛的构建选项和更好的跨平台支持。
- API和模块的调整: PyQt6中的一些模块名称进行了调整,以匹配Qt6的命名约定。例如,尽管QtWidgets和QtGui等核心模块保留了名称,但QString和QVariant等类型被移除,因为Python已经有相应的原生类型。
- 其他变化: 包括但不限于QAction的移动,以及其他API设计和命名上的变化,以提供更一致和更符合Python风格的接口。
如果你正在开始一个新项目,Qt6可能是一个更好的选择,因为它代表了Qt的最新发展方向。
Qt6在线安装流程
Qt6不提供离线安装包,而是推荐使用在线安装工具来下载和安装所需组件。访问Qt官方的在线安装器下载页面:
Qt官方在线安装器下载地址:
Index of /archive/online_installers
下载适用于Windows的在线安装工具。
确保选择与你的操作系统位数相匹配的版本(通常是64位)。
建议去清华大学开源软件镜像站下载Qt相关资源,官网太慢了。
在国内源上下载qt在线安装工具:
#清华大学开源镜像:
https://mirrors.tuna.tsinghua.edu.cn/qt/official_releases/online_installers/
阿里云盘不限速下载地址:
https://www.aliyundrive.com/s/jWM9YtFb7jU
南京大学镜像Mirror
https://mirrors.nju.edu.cn/qt/official_releases/online_installers/
在命令行下打开:
./qt-unified-windows-x64-4.6.1-online.exe --mirror https://mirror.nju.edu.cn/qt
网速好的话,整个安装过程大概持续半个小时左右(前提是使用国内的镜像源)。根据需要选择所需的组件,不需要的组件不用安装,太占空间。
一般选中以下这些就足够了。另外 Additional library中,也可以只选择可能用到的,不用全部安装以节省空间。
附Qt的信号和槽机制介绍
Qt的信号和槽机制是其框架的一个核心特性,它提供了对象间通信的一种类型安全的方式,而无需显式地使用回调函数。信号和槽机制的实现依赖于Qt的元对象系统,其中包括QMetaType和QVariant,以及元对象编译器(MOC)。QMetaType 和 QVariant 是 Qt 的元对象系统如何工作的基础。没有 QMetaType,就不可能有信号和插槽,并且动态调用需要 QVariant。
以下是信号和槽机制的基本工作原理:
元对象编译器(MOC):
MOC是Qt的预处理器,它读取源代码文件,寻找带有Q_OBJECT宏的类声明。
当MOC遇到Q_OBJECT宏时,它会生成额外的代码,这些代码描述了类的元数据,包括信号、槽和属性信息。
元数据存储:
每个带有Q_OBJECT宏的类都会生成一个元数据结构,其中包含了类的所有信号和槽的描述。这些元数据被存储在QMetaObject结构中,每个类都有一个与之关联的QMetaObject实例。
信号和槽的连接:
当你使用QObject::connect()函数连接信号和槽时,Qt会查找信号和槽的元数据,并确保它们的参数类型匹配。
connect()函数会检查信号和槽的QMetaMethod,并验证它们的参数类型和数量是否一致。
动态调用:
当信号被触发时,Qt的事件循环会调用相应的槽函数。
这个过程涉及到使用QMetaObject::invokeMethod()函数,它能够根据QMetaMethod的描述动态地调用槽函数。
QVariant在这里起到了关键作用,它提供了类型安全的参数传递机制,允许信号和槽之间的数据交换。
类型注册:
QMetaType负责类型信息的注册和转换,它允许Qt处理各种数据类型,包括用户自定义类型。
为了使自定义类型能够通过信号和槽传递,你需要使用qRegisterMetaType<T>()函数注册类型。
事件循环:
Qt的事件循环是信号和槽机制的核心,它处理事件队列中的信号,并调度相应的槽函数执行。
通过这种方式,Qt的信号和槽机制提供了一种简洁、类型安全且高效的对象间通信方式,使得程序员可以轻松地构建复杂的应用程序架构,而无需担心底层的细节。
标准C++中有无信号和槽机制?
在标准C++中实现信号和槽机制的主要挑战在于类型安全和元数据的管理。Qt的信号和槽机制利用了元对象系统和元数据来实现类型安全和动态调用,而标准C++中没有这样的机制。因此,你可能需要使用模板和类型推断来确保类型安全,同时使用std::function和std::bind来实现动态调用。
C++对象间的通信可以通过多种方式实现。下面是一些常见的方法:回调函数、观察者模式、事件和消息队列、发布-订阅模式:、依赖注入、共享数据结构等。
Boost C++ Libraries中的Boost.Signals2库提供了一个类似于Qt信号和槽的实现,但它是基于标准C++的。Boost.Signals2提供了类型安全的信号和槽,支持连接和断开连接,以及信号的传递参数。
除了Boost.Signals2,还有一些其他的C++库提供了类似信号和槽的机制,例如:
sigslot:
一个轻量级的信号和槽库。
https://github.com/palacaze/sigslot
sigslot
是一个轻量级的C++信号和槽库,它提供了一种类型安全的机制来处理对象之间的通信。信号和槽机制允许对象在状态变化时通知其他对象,而无需直接调用它们的成员函数。这种机制有助于减少对象之间的耦合,使代码更易于维护和扩展。
该库基于C++14标准编写,只需包含头文件即可使用,无需编译或安装步骤。优点是不用担心空回调,当回调对象析构时会自动disconnect,且支持多线程,线程安全,有锁,缺点是只能回调void类型函数,不支持返回值。boost中的signals库架构类似,支持返回值,但引入了boost中的其他库。且slot没有优先级,不能动态调整回调队列中的先后顺序。
和回调的区别:
回调是个函数指针,缺点有两个,一是类型不安全,你不知道使用者调用回调的对象和参数是否正确;二是过于耦合,处理函数通常要和回调函数一起。
信号插槽机制优点:一是不用担心空指针,插槽对象析构时,会自动断开连接(disconnect);二是线程安全,带锁,不用担心多线程之间的冲突。当然缺点也有,没有返回值即只能是void函数,而且顺序不能调整插槽对象的响应先后。
使用场景:
两个独立的对象或者模块之间,想要直接沟通,但是又不想过多暴露接口,如果联系比较简单,这时可以考虑这个轻量级的消息框架---sigslot,整个库就一个头文件sigslot.h,集成非常灵活。
libsigc++
一个用于C++的信号和槽库。
libsigc++
是一个用于C++的信号和槽库,它提供了一种类型安全的机制来处理对象之间的通信。libsigc++
是 GNOME 项目的一部分,广泛用于 GNOME 桌面环境和其他开源项目中。
CppMicroServices:一个模块化的C++框架,提供了事件和信号机制。
libsigc++ -- The Typesafe Callback Framework for C++: libsigc++
#include <iostream>
#include <string>
#include <sigc++/sigc++.h>
//! 普通函数
void Print(const std::string& str)
{
std::cout << str;
}
int main()
{
//! 返回值void,参数const std::string&
sigc::signal<void, const std::string&> signal_print;
//! 链接函数
signal_print.connect( sigc::ptr_fun(&Print));
//! 发射信号
signal_print.emit("hello world\n");
system("pause");
return 0;
}
简单模拟信号和槽
#include <iostream>
#include <vector>
#include <functional>
class Signal {
public:
void connect(std::function<void()> slot) {
slots.push_back(slot);
}
void emit() {
for (auto& slot : slots) {
slot();
}
}
private:
std::vector<std::function<void()>> slots;
};
class Button {
public:
Signal clicked;
};
class Dialog {
public:
void handleButtonClick() {
std::cout << "Button clicked!" << std::endl;
}
};
int main() {
Button button;
Dialog dialog;
button.clicked.connect(std::bind(&Dialog::handleButtonClick, &dialog));
// Simulate button click
button.clicked.emit();
return 0;
}
其他资源
QT6开发指南-安装_qt6安装-CSDN博客
QT6/5无痛安装和扩展,新手专用_qt6安装-CSDN博客
Qt6安装教程——国内源-CSDN博客
替代notepad++,notepad--介绍及插件cmake编译-CSDN博客
NJU Mirror
Qt6入门教程 1:Qt简介-CSDN博客
https://zhuanlan.zhihu.com/p/335550105
Qt 6的技术概览
Qt6入门教程 7:信号和槽机制(原理和优缺点)_qt6信号槽机制-CSDN博客
标题:Sigslot:一款高效的C++信号槽库-CSDN博客
一个类QT信号槽机制的C++库:sigslot库-CSDN博客
【学习笔记】开源库之 - sigslot (提供该库存在对象拷贝崩溃问题的解决方案)_sigrok源码修改-CSDN博客
C++ 程序设计:信号与槽_c++ 信号槽-CSDN博客
Unix/C++--libsigc++深入理解-CSDN博客
C++ 资源大全:标准库、Web框架、人工智能等 | 最全整理-腾讯云开发者社区-腾讯云
sigslot库--一个简单的C++消息框架-CSDN博客
sigslot库--一个简单的C++消息框架-CSDN博客