Qt版本:6.7.0
CLion版本:24.2.2
CMake版本:3.29
一图胜千言,与其用苍白的文字让读者横加猜测,倒不如图像来的直观些,文字的魅力在于抽象,图片的魅力在于直观
1.使用CLion进行基于Qt Widgets的开发配置
1.1 对项目的基本配置
首先创建Qt6的项目,一定要创建 Qt 微件可执行文件(Qt Widgets Executable) 如下图所示,
创建完成之后可以看到CMake的 Debug 出现提示,即CMake无法找到MinGW进行调试
我们只需要在 CMakeLists.txt 文件中加入 set(CMAKE_PREFIX_PATH "D:/software/Qt6/6.7.0/mingw_64")
,路径自行修改,这一行一定要在find_package
之前
cmake_minimum_required(VERSION 3.29)
project(helloqt)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
# 引入mingw_64下的一些库文件
set(CMAKE_PREFIX_PATH "D:/software/Qt6/6.7.0/mingw_64")
find_package(Qt6 COMPONENTS
Core
Gui
Widgets
REQUIRED)
add_executable(helloqt main.cpp)
target_link_libraries(helloqt
Qt::Core
Qt::Gui
Qt::Widgets
)
# 以下内容省略..
加入上面的配置后,需要重新加载CMake项目以使配置生效,有如下两种重载CMake的方式,
1.在项目区域任意位置右键->重新加载 CMake 项目
2.点击图中所示图标,重新加载CMake项目
此外还可以修改CLion默认配置(如下所示),使项目能够自行识别 CMakeLists.txt 文件的更改从而在保存后能够自动重载(手动重载)
重载之后可以看到顶部菜单栏中已经有了可以运行的按钮,点击运行可以看到成功显示
1.2 配置Qt开发的工具链
之后配置工具链(ToolChain),找到文件->设置,按照下图所示配置MinGW工具链,CLion会自动识别
1.3 配置Designer和UIC
Qt Designer是一个可视化控件设计器,里面包含大量可视化控件,可以用于快速开发,这里进行配置,使得在CLion中可以直接调用该功能,还是在设置中进行配置,配置内容如下图所示,路径需要设置为你自己的安装目录,实参和工作目录要与图中一致
之后配置Qt的UIC用于将 .ui 文件生成 .h 和 .cpp 文件,包括生成特定的ui类,配置如下
为方便复制,这里直接以表格形式呈现
名称 | 实参 | 工作目录 |
---|---|---|
Qt Designer | $FileName$ | $FileDir$ |
Qt UIC | $FileName$ -o ui_$FileNameWithoutAllExtensions$.h | $FileDir$ |
之后我们新建一个ui文件进行测试,在项目中新建 Qt UI 类
设置名字及其父类,这里设置为 Login 并继承自 QWidget 类
点击确定之后项目中多了三个文件
双击 login.ui 文件可以通过 Qt Designer 编辑器打开,也可以通过配置的外部工具 Qt Designer 打开,不用配置外部工具 Qt Designer 也可以,区别在于使用外部工具保存时会记住打开的目录,而双击打开保存时的默认位置为上一次保存的路径。
打开 login.cpp 文件可以看到,里面引入了一个头文件 ui_Login.h ,但是项目目录中并不存在此文件,CLion给出了提示,如图中红框所示,需要我们运行Qt的UIC程序产生,这也是上面配置外部工具 Qt UIC 的作用
先在 login.ui 中简单拖几个控件
然后利用外部工具 Qt UIC 生成 ui_Login.h 文件(需要选中login.ui运行此外部工具)
将 main.cpp 修改为如下内容
#include <QApplication>
#include "login.h"
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
Login login;
login.resize(600,500);
login.show();
return QApplication::exec();
}
点击运行得到了想要的结果,至此配置完毕
1.4 构建
Debug和Release构建都会生成.exe文件,配置MinGW工具链之后,默认是可以进行Debug的但是不能Release,只需要简单配置一下,点击加号之后会自动添加Release功能,Debug版本和Release版本的主要区别就是Debug版本包含了我们的代码信息方便调试
配置之后可以看到菜单栏多了Release选项,运行一下就可以产生相关的Release版本,并生成发行版本的.exe文件(Debug之后也会产生Debug版本的.exe)
我们到Release版本所在的文件夹(上图箭头所示的文件夹)运行 helloqt.exe ,一般来说可以运行成功的,但是我这里报如下错误,
我们将该目录下(自行查找)的 libstdc+±6.dll 复制到 helloqt.exe 同级目录下,即可解决(Debug版本也是同样的操作)
D:\software\Qt6\6.7.0\mingw_64\bin\libstdc++-6.dll
然后运行可以看到如下效果
我们会发现,在弹出想要的界面后,会再弹出一个命令行窗口遮挡住我们自己的界面,我们只需要修改 CMakeLists.txt 文件中的如下内容,然后重新加载CMake项目、构建就可以得到我们想要的结果了。
-add_executable(helloqt main.cpp
+add_executable(helloqt WIN32 main.cpp
可以看到一些对 CMakeLists.txt 的修改是固定的,难道我们每次创建项目都要进行手动修改吗?为了方便,我们可以修改 CMakeLists.txt 的模板,来到设置里面
添加内容为第8行与23行,路径自行修改,下次我们创建项目的时候就能使用这个模板了
cmake_minimum_required(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
project(${PROJECT_NAME})
set(CMAKE_CXX_STANDARD ${CMAKE_LANGUAGE_VERSION})
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_PREFIX_PATH "D:/software/Qt6/6.7.0/mingw_64")
#if( ${CMAKE_MAJOR_VERSION} < 3 || ( ${CMAKE_MAJOR_VERSION} == 3 and ${CMAKE_MINOR_VERSION} < 7 ) )
set(CMAKE_INCLUDE_CURRENT_DIR ON)
#end
#if( ${QT_PATH} != "" )
set(CMAKE_PREFIX_PATH "${QT_PATH}")
#end
find_package(Qt${QT_VERSION} COMPONENTS
#foreach( $library in ${REQUIRED_LIBS} )
$library
#end
REQUIRED)
add_executable(${PROJECT_NAME} WIN32 main.cpp)
target_link_libraries(${PROJECT_NAME}
#foreach( $library in ${REQUIRED_LIBS} )
Qt#if( ${QT_VERSION} < 6 )${QT_VERSION}#end::$library
#end
)
#if( ${WINDOWS} )
#set( $d = "$" )
if (WIN32 AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
set(DEBUG_SUFFIX)
if (MSVC AND CMAKE_BUILD_TYPE MATCHES "Debug")
set(DEBUG_SUFFIX "d")
endif()
set(QT_INSTALL_PATH "${d}{CMAKE_PREFIX_PATH}")
if(NOT EXISTS "${d}{QT_INSTALL_PATH}/bin")
set(QT_INSTALL_PATH "${d}{QT_INSTALL_PATH}/..")
if(NOT EXISTS "${d}{QT_INSTALL_PATH}/bin")
set(QT_INSTALL_PATH "${d}{QT_INSTALL_PATH}/..")
endif()
endif()
if(EXISTS "${d}{QT_INSTALL_PATH}/plugins/platforms/qwindows${d}{DEBUG_SUFFIX}.dll")
add_custom_command(TARGET ${d}{PROJECT_NAME} POST_BUILD
COMMAND ${d}{CMAKE_COMMAND} -E make_directory
"${d}<TARGET_FILE_DIR:${d}{PROJECT_NAME}>/plugins/platforms/")
add_custom_command(TARGET ${d}{PROJECT_NAME} POST_BUILD
COMMAND ${d}{CMAKE_COMMAND} -E copy
"${d}{QT_INSTALL_PATH}/plugins/platforms/qwindows${d}{DEBUG_SUFFIX}.dll"
"${d}<TARGET_FILE_DIR:${d}{PROJECT_NAME}>/plugins/platforms/")
endif()
foreach(QT_LIB #foreach( $library in ${REQUIRED_LIBS} )$library #end)
add_custom_command(TARGET ${d}{PROJECT_NAME} POST_BUILD
COMMAND ${d}{CMAKE_COMMAND} -E copy
"${d}{QT_INSTALL_PATH}/bin/Qt${QT_VERSION}${d}{QT_LIB}${d}{DEBUG_SUFFIX}.dll"
"${d}<TARGET_FILE_DIR:${d}{PROJECT_NAME}>")
endforeach(QT_LIB)
endif()
#end
1.5 qrc文件的配置
我们知道Qt Creator中可以通过.qrc文件引入一些我们自己的资源,比如图片、音视频以及QSS等,qrc文件会被Qt的资源编译器rcc处理,将资源文件直接编译到最终的应用程序可执行文件中。这样做的好处是,资源文件成为了应用程序的一部分,可以随应用程序一起发布和部署,而无需单独管理资源文件的路径和版本。那么在CLion中如何使用.qrc文件呢?
首先在根目录下创建一个 helloqt.qrc 文件,以及资源目录,具体的内容如下
在 login.qss 改变一下登录按钮的背景色,内容如下:
QPushButton { background-color: red}
helloqt.qrc 的内容如下,其中 prefix 为虚拟前缀,file 标签中为资源的相对路径,我们在引入资源时例如loginIcon.png,路径应该为 :虚拟路径:资源的路径 即 “:resources/resources/images/loginIcon.png”
<RCC>
<qresource prefix="resources">
<file>resources/images/loginIcon.png</file>
<file>resources/qss/login.qss</file>
</qresource>
</RCC>
在 login.cpp 中引入一下 login.qss
#include "login.h"
#include "ui_Login.h"
Login::Login(QWidget *parent) :
QWidget(parent), ui(new Ui::Login) {
ui->setupUi(this);
// 引入样式
QFile styleFile(QString(":resources/resources/qss/login.qss"));
styleFile.open(QFile::ReadOnly);
if (styleFile.isOpen()){
this->setStyleSheet(styleFile.readAll());
styleFile.close();
}
}
Login::~Login() {
delete ui;
}
在 ui_login.h 中加入如下内容:
pushButton = new QPushButton(Login);
pushButton->setObjectName("pushButton");
pushButton->setGeometry(QRect(230, 360, 101, 24));
+QIcon icon;
+icon.addFile(QString::fromUtf8(":/resources/resources/images/loginIcon.png"), QSize(), QIcon::Normal, QIcon::Off);
+pushButton->setIcon(icon);
最后修改 CMakeLists.txt ,引入 .qrc 文件参与编译:
cmake_minimum_required(VERSION 3.29)
project(helloqt)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_PREFIX_PATH "D:/software/Qt6/6.7.0/mingw_64")
# 设置 helloqt.qrc 的路径
set(QRC_SOURCE_FILE helloqt.qrc)
find_package(Qt6 COMPONENTS
Core
Gui
Widgets
REQUIRED)
# 引入 helloqt.qrc 中指定的资源
qt_add_resources(${QRC_SOURCE_FILE})
# 参与编译
add_executable(helloqt WIN32 main.cpp
login.cpp
login.h
login.ui
${QRC_SOURCE_FILE}
)
target_link_libraries(helloqt
Qt::Core
Qt::Gui
Qt::Widgets
)
# 以下内容省略..
之后重新加载CMake,点击运行,得到了想要的结果
我们既可以在CLion中手动书写 .qrc 里的内容,也可以在Qt Designer编辑器中设置,再通过外部工具 Qt UIC 转化 .ui 文件生成所需的 .qrc 文件(这里指的是 .qrc 里的内容, .qrc 文件本身需要自己创建)等。
1.6 打包发布
1.6.1 手动归纳发布版本
上面我们提到了通过配置Release之后,可以产生Release版本的exe文件,我们想把它发给其他人使用该发送什么文件呢,只有exe肯定是不够的还需要其所需的一些Qt库文件,但是我们发现 cmake-build-release 下的文件也太多了,虽然说全部打包发给别人也可以但是不够简洁,因为里面一大堆和运行程序无关的文件和目录。其实我们只需要把红框里的内容打包发给别人就可以了,需要注意 libstdc++-6.dll 动态链接库是我们自己添加的而非自动生成。
除此之外,我们还可以在 CMakeLists.txt 文件进行如下配置(添加第12行与第14行内容),将打包所需的文件直接在自定义的目录下生成,${CMAKE_CURRENT_SOURCE_DIR}
为项目所在根目录
cmake_minimum_required(VERSION 3.29)
project(helloqt)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_PREFIX_PATH "D:/software/Qt6/6.7.0/mingw_64")
set(QRC_SOURCE_FILE ${PROJECT_NAME}.qrc)
# 设置release版本的输出目录变量
set(PUBLISH_BIN_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/Release)
# 设置之后,会将release版本的所需文件生成在指定目录
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PUBLISH_BIN_RELEASE})
find_package(Qt6 COMPONENTS
Core
Gui
Widgets
REQUIRED)
qt_add_resources(${QRC_SOURCE_FILE})
add_executable(helloqt WIN32 main.cpp
login.cpp
login.h
login.ui
${QRC_SOURCE_FILE}
)
target_link_libraries(helloqt
Qt::Core
Qt::Gui
Qt::Widgets
)
# 忽略其余内容
设置之后再次执行菜单栏的Release会得到如下文件,如果在初次Release时就对输出目录进行了设置,那么 cmake-build-release 下将不再生成 Release 目录下的文件,当然要想成功运行exe,还是需要手动添加 libstdc+±6.dll 文件
1.6.2 借助windeployqt打包
另外我们还可以借助Qt提供的工具 windeployqt 进行打包,有两种方法
1.将 windeployqt.exe 所在的目录加入到环境变量中,在 Release 目录运行cmd执行如下命令进行打包部署。
windeployqt.exe helloqt.exe
2.添加外部工具Qt Deploy(名字任意),设置如下(具体可以参考外部工具Qt Designer的设置), windeployqt.exe 的路径自行修改
配置好之后我们只需要选中 helloqt.exe 右键运行外部工具 Qt Deploy 即可,得到的内容如下,很明显这个包里面增加了许多额外内容,体积会变的非常大(~69M,原来只有~23M),但是会帮我们自动添加 libstdc+±6.dll 文件,还需要注意 qwindows.dll 文件重复了,只需要删除 plugins 目录即可。
其实执行windeployqt.exe helloqt.exe
,只需要 hello.exe 文件,我们可以将其余文件删除只保留 hello.exe ,然后再执行外部工具 Qt Deploy 就可以了,好处是不需要手动删除重复的 qwindows.dll 文件,这也可以在 CMakeLists.txt 文件中配置如下(第38~43行内容,连同第12行和第14行内容),这样在执行 第一次执行relase 之后会在项目根目录下产生 Release 目录,之后在项目目录空白处点击 重新加载CMake项目,然后 再执行一次release ,就可以看到 Release 目录下只有helloqt.exe ,加入if判断是为了项目初始化时因为尚不存在Release目录而报错
cmake_minimum_required(VERSION 3.29)
project(helloqt)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_PREFIX_PATH "D:/software/Qt6/6.7.0/mingw_64")
set(QRC_SOURCE_FILE ${PROJECT_NAME}.qrc)
# 设置release版本的输出目录变量
set(PUBLISH_BIN_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/Release)
# 设置之后,指定release版本的生成目录
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PUBLISH_BIN_RELEASE})
find_package(Qt6 COMPONENTS
Core
Gui
Widgets
REQUIRED)
qt_add_resources(${QRC_SOURCE_FILE})
add_executable(helloqt WIN32 main.cpp
login.cpp
login.h
login.ui
${QRC_SOURCE_FILE}
)
target_link_libraries(helloqt
Qt::Core
Qt::Gui
Qt::Widgets
)
# 只保留Release目录下的helloqt.exe
if (EXISTS ${PUBLISH_BIN_RELEASE}/${PROJECT_NAME}.exe)
file(COPY ${PUBLISH_BIN_RELEASE}/${PROJECT_NAME}.exe DESTINATION ${CMAKE_CURRENT_SOURCE_DIR})
file(REMOVE_RECURSE ${PUBLISH_BIN_RELEASE})
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.exe DESTINATION ${PUBLISH_BIN_RELEASE})
file(REMOVE ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.exe)
endif ()
# 省略其余内容
1.6.3 借助Enigma Virtual Box将应用程序打包成一个exe文件
通过Qt自带的打包工具打包后,将 Release 文件夹直接发给其他人就可以了,别人只需要点击exe就可以运行,但是这还不够简洁优雅,我们还可以将程序的依赖文件连同程序本身直接打包进一个exe文件中,也就是说你只需要把一个exe文件发给别人就可以直接运行,话不多时,开始操作
首先下载 Enigma Virtual Box软件虚拟化工具 ,然后点击安装即可
接着运行 Enigma Virtual Box ,在第一步选中源程序 helloqt.exe ,封包程序路径以及名字可以自定义,第二步将除了 helloqt.exe 的其余文件和文件夹一起拖到箭头所示的空白区域内,第三步点击 确定 ,第四步点击 执行封包 。最终会得到 helloqt_boxed.exe ,它的大小有~69M,所以只需要这一个文件就可以了,其余文件都删除之后依然可以运行。
1.7 参考博文
3.QT生成的exe无法定位程序输入点 于动态链接库 报错原因
4.Clion+Qt,在运行exe文件时出现黑窗口的解决方案
评论区