侧边栏壁纸
博主头像
琉璃红梅 博主等级

琉璃世界,白雪红梅。

  • 累计撰写 44 篇文章
  • 累计创建 90 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录
Qt6

CppQt6系列-使用CLion进行优雅的Qt6开发

雪穗
2024-12-16 / 0 评论 / 0 点赞 / 45 阅读 / 0 字
温馨提示:
本文最后更新于39天前,若内容或图片失效,请留言反馈。 若部分素材不小心影响到您的利益,请联系我删除。

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 参考博文

1.Mac 上 CLion 搭建 QT6.6 开发环境

2.最新QT6.4.0+Clion2023.1.3配置

3.QT生成的exe无法定位程序输入点 于动态链接库 报错原因

4.Clion+Qt,在运行exe文件时出现黑窗口的解决方案

5.Qt_CLion中配置资源文件

6.Clion中QT6的配置,外部工具与打包

7.qrc资源文件:原理、应用与使用方法

8.使用Qt6 和现代 c++ 进行跨平台开发 14:部署 Qt 应用程序

9.QT应用编程: 使用Enigma Virtual Box 封装单执行文件

0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区