先说明一下,本水文老周仅讨论新版的 Qt 6,旧版的 Qt 不讨论。

尽管 Qt 有自己的开发环境,但老周必须说句不装逼的话:真的不好用。说起写代码,当然了,用记事本也能写。但是,有个高逼格的工具,写起来不仅效率高,而且舒服。

Qt 应用程序本质上就是 C++ 开发的代码,所以,不用官方工具是没有问题的。老周第一个想到的,不用猜,必是 VS。在 Windows 上,用 VS 也是没问题的。

安装的时候,工作负载可以选“使用C++的桌面开发”,这个其实不选也可以的,老周已做过实验,不选这个也能编译。所以,可以在单个组件中安装以下各项:

1、C++核心功能;

2、C++ 2022 可再发行程序更新包;

3、MSBuild(这个装上好一点,不装也没报错);

4、MSVC 143 C++ 生成工具(这个是重点,要装,要装);

5、用于 Windows 的 CMake 工具(这个也必须装上);

6、Windows SDK 任选一个版本,建议越新越好(自己编译源代码时必须)。

7、其他的组件自己看心情。

如果你不用 VS,但在 Windows 上也要装 MSVC 生成工具。在 Windows 上还是建议用微软的编译器,不容易出现莫名其妙的错误。老周实验过,用 Windows 版的 g++ 编译失败。

当然本文讲的  VS Code,但如果是 Windows 平台,也要装 VS 生成工具的。

-----------------------------------------------------------------------------------------------------------------------

编译源代码

Qt 现在也开始装X了,编译好的内裤只支持在线安装,十有八九慢到你要装几天才能装好,而且体积比 VS 还要大几倍。想离线安装只能下载源代码自己编译。

编译源代码需要以下工具:

1、Windows SDK,否则会找不到相关 .lib 文件而出错。

2、Python,3.x 后随便找个版本。可以下载嵌入版,不用安装,解压后,把Python可执行文件所在的目录路径添加到 PATH 变量中。

3、Perl。可以下载绿色版压缩包,解压到某目录,将包含 perl.exe 的目录添加到 PATH 环境变量中,一般位于 <解压后目录>\Perl\perl\bin。

下载源码可以用国内镜像,如清华大学的:Index of /qt/archive/qt/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror

最新的是 6.3,进去之后,不要下载整个源码包,而是找到 submodules 目录。核心组件是 qtbase-everywhere-6.xxx。

qtbase 是基础包,只编译这个模块的代码也能写 Qt 程序。解压之后,放在一个路径无空格无特殊符号的目录下,如 E:\SDK\Qt。然后执行一下 configure 脚本,Windows 上是有后缀 .bat 的,Linux 脚本无后缀。

命令行参数可参考帮助文档,实际上我们只关心一个参数 -prefix。这个参数指定在编译成功后,复制(安装)动态库的目录。因为编译时会产生许多后期没用的文件,所以才要指定这个路径。操作方法:

打开 “Visual Studio 2022” -- "x64 Native Tools Command Prompt for VS 2022"。

不要用 Developer Command Prompt for VS 2022,因为用这个你要指定 CPU 架构,若不指定默认编译出来的库是 32 位的。

【注意:下面输入命令这一大段,你先别着急跟着输入。请你先看完了再输入。因为这 Qt 6 在编译前的配置有些雷区。即在“+++++++++++”与“+++++++++++”之间这一大段内容】

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

先看最保险的操作,全按官方文档的来,基本保持默认。

打开 x64 Native Tools Command Prompt for VS 2022 工具的命令提示窗口,输入:

cd <源码路径> 
configure -prefix F:\Qt6\Libs

这样配置之后,将来在执行安装时会把生成的 .dll 复制到这个目录下。这厮好像重复执行会报错。老周一般是懒得去找错误,有时候就算找到错误在哪个 cmake 文件也解决不了问题,最直接有效的方法是全删掉,再从下载的压缩包里重新解压。官方文档说删除 CMakeCache.txt 文件可以,但老周尝试过,也是会报错的。

一切顺利之后,直接交给 CMake 解决。编译:

cmake --build .

. 是源码所在目录,因为上面我们已经 cd 到源码目录了,所以这里用个“.”表示当前目录。

运气好的话,一次通过。这时候电脑的 CPU 风扇会发疯,请做好心理准备。因为只编译一个基础模块,所以花的时间会少一些。

编译成功后,还要执行一下安装操作:

cmake --install .

后面的“.”依然指的是当前目录(源码目录),编译后的二进制文件(重点是那些 .dll)会复制到你刚才用 -prefix 参数配置的路径下。如刚才配置的是 F:\Qt6\Libs。

上面的方案是保证出错概率最低的做法,但是,生成文件会和源码混在一起,想手动清理它们估计会累死人。如果想三个基本目录相互隔离,就要用接下来的方法。这三个目录是:

1、源码。

2、build 输出目录。

3、安装目录。

我们来假设一下:

1、源代码:G:\Kits\Qt6\src\qtbase

2、build 输出目录:G:\Kits\Qt6\build

3、安装目录:G:\Kits\Qt6\installed

其实,这些目录都在 G:\Kits\Qt6 下面。

废话一下,我现在的想法是:保留源代码目录不变,想留着将来重复用;把生成/编译输出的东东放在 build 目录,编译好后的二进制文件安装到 installed 目录。下面开始操作。

【警告:以下操作出现灵异事件的概率大,请鼓起勇气尝试。世事难料,各自珍重】

首先,打开 x64 Native Tools Command Prompt fo VS 20XX,定位到 G:\Kits\Qt6\build,这个路径要根据你实际的路径写。

cd /d G:\kits\Qt6\build

命令工具窗口当前目录一般是 C 盘,要跨分区 CD 的话,要加上 /d 参数。

保持 build 目录为当前目录不要改变,在 build 目录中执行 configure 脚本。

..\src\qtbase\configure -prefix ..\installed

老周这里用的是相对路径,你也可以用绝对路径。注意 -prefix 参数是一个短横线的,不能写成 --prefix,会出错。如果看到下面这一行,说明你运气好,第一关算是过了,接下来的编译成功率很高。

Build files have been written to: G:/Kits/Qt6/build

接下来的操作就和前面的一样了。保持当前目录在 build 不变,依次执行:

cmake --build .
cmake --install .

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

大约会编译 1700 多个目标。这过程中很有可能会出错退出。可以尝试重新执行 cmake --build . ,一般会成功的。 在 installed\bin 目录下你会看到许多 .dll,这说明一切顺利。

编译默认是生成动态库的,所以在 configure 时我们不用改。建议用动态库,若编译为静态库,做项目时会涉及授权问题,也就是说你要购买。

配置 VS Code

编译完毕后,就是配置 VS Code 了,其实就是安装插件罢了。这几个插件少不了:

1、C/C++(微软官方的)

2、CMake Tools(也是微软官方的)

3、CMake Language Support(有了这个,写CMake时有智能提示)

有以上这几个就够玩了。另外,微软有个集合包,叫做 C/C++ Extension Pack,会一次安装一堆 C++ 有关的插件。觉得有必要可以装装,觉得没必要就当它透明。

打开 VS Code 的设置页,找到扩展中的 CMake Tools,滚动到 Environment,点“添加项”设置一个环境变量。

PATH = G:\Kits\Qt6\installed;G:\Kits\Qt6\installed\bin;%PATH%

【键】是“PATH”,【值】是 = 后面那串。路径就是你刚才 Qt6 安装的目录,包括安装目录,以及安装目录下的 bin。

保存退出,收工。

开始装逼

如果上面各步骤都成功,我们现在可以开写玩了。

在 VS Code 中打开一个目录作为工作区。然后按 【ctl + shift + P】,输入“cmake”,找到“CMake 配置”命令,执行。

编译器选择 amd64 的,如果你要 32 位的就选 x86。

【注】如果你要写 32 位的,那前面在编译源代码时也要编译一份 32 位的动态库。这个你懂的,32 位和 64 位的二进制文件是不同混用的。

这时,提示还没创建 CMakeLists.txt ,那就点创建呗。但是,生成的 CMakeLists.txt 文件中的东东很多不是我们所需要的。凡是有 enable_testing,CTest 什么的,全部干掉。

大致内容如下:

cmake_minimum_required(VERSION 3.15.0)

# 项目名称
project(testApp LANGUAGES CXX) # 设置变量
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON) # 引用需要的库
find_package(Qt6 REQUIRED COMPONENTS Core Widgets Gui)
# 添加源代码文件
add_executable(testApp WIN32 main.cpp)
# 与相关的库链接
target_link_libraries(testApp PRIVATE Qt6::Widgets Qt6::Core Qt6::Gui)

1

cmake_minimum_required(VERSION 3.15.0)
设置要使用的 CMake 最小版本号,这个你看情况写吧,我这里写 3.15。
 
2:设置项目的名称,这个也是自己定义的,比如你的项目叫 KillDog。
project(KillDog LANGUAGES CXX)
CXX 表示 C++ 语言。

3:设置变量。

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)

CMAKE_CXX_STANDARD = 17     C++版本号 ,不要低于17。

CMAKE_CXX_STANDARD_REQUIRED = on 或 yes 或 1,和上面一起,必须符合C++版本。

CMAKE_AUTOMOC = on 或 yes 或 1,这个在Qt 项目里一般要开启,允许一些独特语法转译为C++代码。说白了就是 Qt 里面的信号和槽,用到特定的语法(其实这些语法是用宏定义的)。

CMAKE_AUTOUIC = on 或 yes 或 1,这个如果用到了 uic 资源时才会开启,没用到就可以不写。

4:引入要使用的库,Qt6 中使用 find_package 命令,格式都是固定,官方文档中有,可以照着抄。

5:添加源代码文件。

add_executable(testApp WIN32 main.cpp)

第一个是目标名,一般和项目名称相同,你可以自己取名。接着 WIN32 不能少(仅限于 Windows),否则窗口出不来,只出来控制台。main.cpp是代码文件,有多个代码文件也要写上,比如 a.cpp b.cpp c.cpp,如果写漏了就导致有的文件没有被编译,那你的程序能运行起来才怪呢。

6:链接。把目标(上面 add_executable 就是为目标加了源文件)和库链接起来。

target_link_libraries(testApp PRIVATE Qt6::Widgets Qt6::Core Qt6::Gui)

这个格式也是固定的,照着文档抄就行了。请看上面 find_package 的截图。

----------------------------------------------------------------------------------------------------------------------------------

下面是 main.cpp 中的代码,我们来试试前面的配置是否正确。                           ,

#include <QApplication>
#include <QWidget>
#include <QHBoxLayout>
#include <QPushButton>
int main(int argc, char** argv) 
{
// 这个 App 和 Widgets 在代码上不直接引用
// 但它是必须的,它会开启主消息循环
QApplication app(argc, argv); // 准备主窗口
QWidget window;
// 窗口标题
window.setWindowTitle("穷屌丝应用程序");
// 设置窗口大小
window.resize(400, 300); // 控件
QPushButton *btn1 = new QPushButton("第一个按钮");
QPushButton *btn2 = new QPushButton("第二个按钮"); // 布局
QHBoxLayout *layout = new QHBoxLayout(&window);
// 将控件放入布局中
layout -> addWidget(btn1, 2);
layout -> addWidget(btn2, 1); // 显示窗口
window.show(); // 别忘了这一行,正式启动程序
return app.exec();
// 调用静态的也行
//return QApplication::exec();
}

QApplication 类用于启动应用程序的主消息循环,它不需要显式引用 Widget 对象。调用 exec 方法正式开始消息循环。这个方法会一直循环,直到应用程序退出(主窗口/根 Widget 被关闭)才会返回。若无错误,就返回 0 ,这个返回值可以直接沿着 main 函数返回。

注意,所有初始化(创建窗口,放置控件等)代码必须在 exec 方法之前调用。exec 方法一旦调用,除非应用程序退出,否则是不会返回的。所以不要在 exec 之后写任何代码(清理代码除外)。

QWidget 是众多 UI 元素/控件的基类,直接使用它可以作为应用程序的窗口——就是一个空白窗口。setWindowTitle 方法用来设置窗口标题栏上的文本;resize 方法调整窗口的大小;show 方法显示窗口。

QHBoxLayout 是一个布局类,用来布局窗口中控件的位置。它指的是 UI 元素沿水平方向排列。这个 Layout 类似于 WPF 中的 StackPanel。嗯,相信你也猜到,要垂直布局,就用 QVBoxLayout 类。如果想向 StackPanel 那样,可以通过设置来控制水平或垂直方向,可以用 QBoxLayout,通过 setDirection 方法可以设置:从左到右、从右到左、从上到下、从下到上。

QPushButton 就是常见的按钮。

在 Qt 应用程序中,new 出来的指针不一定要 delete / free 的。因为它有个引用树的概念,会自动释放指针所引用的东西。前提是这些对象是连接到 QObject 上的。比如窗口是 QWidget ,放在窗口内的控件元素如果以窗口为父对象,就像上面那个例子,里面的 QHBoxLayout、QPushButton 等,是连接到 QWidget 上的,所以不需要 delete 指针,它会自动释放。

我们 build 一下这个项目,然后运行它。

注意看 VS Code 底部的状态栏,你能找到这两个按钮。

如果没有问题,就能看到应用程序窗口了。

在 Linux 上的编译和配置与 Windows 上差不多的。注意先安装 g++,选这个编译的话可避免各种灵异事件。老周在 Ubuntu 上试验时,曾经遇到过一次灵异事件,至今无法解释。编译 Qt6 源代码顺利完成,写一个 app 试了下也能运行起来。但是,系统重启后就进不了系统了,除了 root 帐户外,所有帐户都无权限登录。切换到 init 2 登录也不行,一登录就会被弹出来。就是除 root 外所有用户都没有任何权限,连登录的权限都没有。这现象无法解释,因为那次老周成功登入系统后只编译了 Qt6 源码,写了个测试 app,也没做别的事,重启后就挂了。

最新文章

  1. Go语言 字符串处理
  2. ScrollView嵌套RecyclerView时滑动出现的卡顿
  3. Mysql EF Code First
  4. iOS 阶段学习第九天笔记(内存管理)
  5. 计算机组成原理 及CPU,硬盘,内存三者的关系
  6. ipvsadm命令使用方法
  7. ttttttttttt
  8. iostat的深入理解
  9. hdu 1074(状态压缩dp+记录路径)
  10. Keil MDK中使用pc-lint的详细方法
  11. [译]Selenium Python文档:五、Waits等待
  12. 自定义TextView跑马灯
  13. Spring IOC原理解读 面试必读
  14. 剑指Offer 54. 字符流中第一个不重复的字符 (其他)
  15. bootstrap3相关文档
  16. JWT操作(.net)
  17. Android开发问题积累 &lt;加载在线Gif&gt;&lt;WebView无法加载网页图片&gt;
  18. 微信小程序接入腾讯云IM即时通讯(会话列表)
  19. css 之单行文本显示省略和多行文本省略
  20. Educational Codeforces Round 10 A. Gabriel and Caterpillar 模拟

热门文章

  1. netty系列之:netty中常用的xml编码解码器
  2. GO 语言入门(一)
  3. mysql Bad handshake
  4. 常见的邮箱服务器(SMTP,POP3)地址,端口
  5. 136_Power BI 自定义矩阵热力图
  6. 解决 AMD 笔记本不插电源时屏幕偏暗的问题
  7. 世界排名前三的Linux桌面发行版
  8. Number.prototype.toString()方法
  9. net core天马行空系列-可用于依赖注入的,数据库表和c#实体类互相转换的接口实现
  10. VmWare安装Centos8注意事项