用VS Code搞Qt6:编译源代码与基本配置
先说明一下,本水文老周仅讨论新版的 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
3:设置变量。
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:添加源代码文件。
第一个是目标名,一般和项目名称相同,你可以自己取名。接着 WIN32 不能少(仅限于 Windows),否则窗口出不来,只出来控制台。main.cpp是代码文件,有多个代码文件也要写上,比如 a.cpp b.cpp c.cpp,如果写漏了就导致有的文件没有被编译,那你的程序能运行起来才怪呢。
6:链接。把目标(上面 add_executable 就是为目标加了源文件)和库链接起来。
这个格式也是固定的,照着文档抄就行了。请看上面 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,也没做别的事,重启后就挂了。
用VS Code搞Qt6:编译源代码与基本配置的更多相关文章
- 用 VS Code 搞Qt6:使用 PySide 6
一般来说,用C++写 Qt 应用才是正宗的,不过,为了让小学生也能体验 Qt 的开发过程,或者官方为了增加开发者人数,推出了可用 Python 来编程的 Qt 版本.此版本命名比较奇葩,叫 PySid ...
- 用VS Code搞Qt6:编译附加模块
上一次水文中,老周所介绍的是编译 Qt 的基础模块-- qtbase.一次性编译所有代码可以一劳永逸,但体积相当大,编译时间较长,CPU负载大发热大,风扇转得猛,电费交得多.因此老周更喜欢分开来编译. ...
- 用VS Code搞Qt6:至简窗口部件——QWidget
在正题开始之前,老周照例扯点别的.嗯,咱们扯一下在 VS 2022 下结合 CMake 开发 Qt6 时的环境变量设置问题.在VS Code 中,通够通过 CMake Tools 扩展的配置来设置环境 ...
- 用 VS Code 搞 Qt6:信号、槽,以及QObject
Qt 里面的信号(Signal)和槽(Slot)虽然看着像事件,但它实际上是用来在两个对象之间进行通信的.既然是通信,就会有发送者和接收者. 1.信号是发送者,触发时通过特有的关键字"emi ...
- 用 VS Code 搞 Qt6:让信号和槽自动建立连接
Qt 具备让某个对象的信号与符合要求的槽函数自动建立连接.弄起来也很简单,只要调用这个静态方法即可: QMetaObject::connectSlotsByName(...); connectSlot ...
- Ubuntu下Code::Blocks无法编译 /bin/sh: 1: g++ not found 解决办法
Linux下Code::Blocks无法编译运行提示 /bin/sh: 1: g++ not found 的解决办法 今天在Ubuntu 12.04 软件中心中选装了Code::Blocks,安装完成 ...
- 使用Visual Studio Code开发(编译、调试)C++程序
总体安装步骤 安装VSC(Visual Studio Code). 安装C/C++编译器(如MinGW-w64),然后配置好环境变量.//完成这步即可在VSC的终端(命令行)下编译.运行.cpp程序了 ...
- golang编译源代码和交叉编译方法
目录 golang编译源代码和交叉编译方法 编译源代码 编译go1.4 编译go1.12 交叉编译 golang编译源代码和交叉编译方法 编译源代码 golang编译其实很简单,下载一份最新的源代码后 ...
- visual studio code使用MSVC编译C++
环境 OS::Microsoft Windows [Version 10.0.17134.285] x64 VSC:Version:1.27.2 (system setup) VS:2017 心血来潮 ...
随机推荐
- 开源框架 WebFirst 一键生成项目,在线建表
1.WebFirst框架描述 WebFirst 是果糖大数据团队开发的新一代 高性能 代码生成器&数据库设计工具,由.net core 3.1 + sqlsugar 开发 导入1000个表只 ...
- 记录在EF Core级联更新时出现的错误The database operation was expected to affect 1 row(s), but actually affected 0 row(s) (低级错误导致)
错误提示:The database operation was expected to affect 1 row(s), but actually affected 0 row(s); data ma ...
- 国内访问 git 慢的方法
在国内访问 git 的时候,总会存在访问慢或者git clone 的时候报下面的错误 这个时候,我们可以使用代理的方式去进行访问 需要注意的是:你必须存在一个国外的,能够让你快速访问到 GitHub ...
- 用更云原生的方式做诊断|大规模 K8s 集群诊断利器深度解析
背景 通常而言,集群的稳定性决定了一个平台的服务质量以及对外口碑,当一个平台管理了相当规模数量的 Kubernetes 集群之后,在稳定性这件事上也许会"稍显被动". 我们可能经常 ...
- 第30章 LeetCode 72 编辑距离
每日一句 A flower cannot blossom without sunshine, and man cannot live without love. 花没有阳光就不能盛开,人没有爱就不能生 ...
- React中使用react-player 播放视频或直播
业务中需要播放视频,寻来寻去,找到了react-player 初次点击,甚是眼熟,思来想去,竟是钉钉同款 如果使用react框架 先安装 npm install --save video-react ...
- Redis集群搭建 三主三从 docker版 急速搭建
最近学习了docker 发现使用docker搭建一个redis非常的简单接下来就是搭建步骤 1.首先清空一下容器 #清空所有容器docker rm -f $(docker ps -aq) 2.然后创 ...
- 万字剖析Ribbon核心组件以及运行原理
大家好,本文我将继续来剖析SpringCloud中负载均衡组件Ribbon的源码.本来我是打算接着OpenFeign动态代理生成文章直接讲Feign是如何整合Ribbon的,但是文章写了一半发现,如果 ...
- Python爬虫-正则
介绍: 是 一门全新的语言,一种使用表达式的方式对字符串进行匹配的语法规则 我们抓取到的网页源代码本质上就是一个超长的字符串,想从里面提取内容,用正则再适合不过 优点:速度快.效率高.准确性高 缺点: ...
- SAP APO-供应链监控
供应链监控(SCM)是一种有效的工具,可以为供应商和购买者做出明智的决策. 供应链流程中的关键人物基于供应链监控做出决策. 供应链包括两个工具- 库存需求清单MD04 物流信息系统(LIS) 事务MD ...