Qt6.5 CMake项目配置

news/2024/5/20 2:53:14 标签: Qt, Qt6, CMake, C++, qrc, ts

Qt65_CMake_0">Qt6.5 CMake项目配置

参考Qt 安装文档
参考Qt CMake文档

Qt CMake配置与版本关联度比较高,不过Qt6.5以后的版本应该差不多

但是Qt6.5之前的配置方法可能就不同了,比如qt_standard_project_setup()可能就是不可用的

Qt_9">配置Qt路径

Qt安装后,Qt并没有被自动添加到系统环境下

设置CMakeCMAKE_PREFIX_PATH

set(CMAKE_PREFIX_PATH "/opt/Qt/6.5.2/gcc_64;${CMAKE_PREFIX_PATH}")

这个目录为Qt编译器目录,是binincludemodules目录所在的目录

设置C++版本

Qt6是基于C++17构建的,所以需要设置C++版本

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

Qt_30">获取Qt

使用find_package函数,具体格式如下

find_package(Qt6 REQUIRED COMPONENTS LinguistTools Core Widgets)
  • LinguistTools,翻译工具,需要启用多语言的会用到这个库,提供了CMake配置ts文件的工具,不需要链接
  • Core,Qt的Core库,提供了头文件和库列表,需要链接
  • WidgetsQt的Widgets库,QWidget等类都在这个模块下,需要链接

Qt_CMake_42">设置Qt CMake通用配置

这一步是最重要的,也是最容易出问题的地方,需要用到qt_standard_project_setup()

这个函数在Qt6.3才被引入,更早的版本都没法使用这个函数

使用时只要添加这个函数到CMake里面即可

qt_standard_project_setup()

配置源代码和UI文件

在项目里添加源文件和头文件,以及对应的UI文件,项目结构如下

.
├── CMakeLists.txt
├── main.cpp
├── MainWindow.cpp
├── MainWindow.h
├── MainWindow.ui
└── README.md

Qt提供了一个qt_add_executable函数,用法和CMakeadd_executable一致

ui文件可以和普通代码文件一样,直接添加,Qt提供的工具,告诉了CMake这些UI文件该怎么处理

qt_add_executable(
    ${PROJECT_NAME}
    main.cpp
    MainWindow.h
    MainWindow.cpp
    MainWindow.ui
)

到这一步为止,一个基本的Qt程序就基本完成了,只要链接对应的库就可以运行

没有翻译文件,也没有资源文件

注意:ui文件会被UIC生成一个头文件;
但是这个头文件在构建项目的时候不会生成;
只有在编译的时候才会生成;
因此,当在cpp文件中添加头文件时报错,不要担心;
编译一次就可以解决;

添加资源文件

如果程序不需要资源文件,可以直接忽略

Qt下,这个资源文件不要自己添加,只要在CMake中配置就行

CMake会调用Qt工具,自动生成qrc文件

qrc中需要添加的文件路径,前缀等,都在CMake中配置

详细用法,可以参考Qt文档qt_add_resources

该模块依赖与Core模块

find_package(Qt6 REQUIRED COMPONENTS Core)

基础用法如下:

qt_add_resources(
    ${PROJECT_NAME}
    ${PROJECT_NAME} PREFIX "/" FILES
    README.md
)

第一个${PROJECT_NAME}是目标项目,第二个${PROJECT_NAME}是文件名

README.md就是要添加的文件,因为该文件和CMakeLists文件在同一个文件夹下,所以直接写了文件名

可以在后面添加更多的文件

添加翻译文件

翻译文件以ts结尾

CMake中,不要创建ts文件,CMake会自动生成

添加翻译文件会用到qt_add_translations函数

该函数需要依赖LinguistTools模块

find_package(Qt6 REQUIRED COMPONENTS LinguistTools)
qt_add_translations(
    ${PROJECT_NAME}
    TS_FILES
    "${PROJECT_NAME}_en.ts"
    "${PROJECT_NAME}_fr.ts"
)

第一个参数是添加目标,然后给一个TS_FILES标记,表示后面的都是ts文件了

可以一次添加多个ts文件

具体用法可以参考Qt文档:qt_add_translations

这个函数会在CMake项目里添加两个目标:update_translationsrelease_translations

就像add_executable添加出来的xxx目标一样

CMakeQt是通过运行这两个目标的方式实现更新翻译文件的

可能会感到有点奇怪,但是这就是他们的实现机制,不要过多考虑

此时并没有ts文件,需要单独运行构建目标的命令

运行下面的命令更新ts文件

$ cmake --build . --target update_translations

再运行下面的命令生成qm文件

$ cmake --build . --target release_translations

注意:这两个目标必须按顺序单独执行,不能build all,否则ts文件会生成异常

最后,生成的qm文件被自动添加到了qrc资源文件里面,前缀是/i18n

添加头文件目录和链接库

这部分主要是头文件目录的指定

在模块被发现后,会自动设置一些变量,头文件目录就是其中一个

比如Widgets模块,其头文件目录就是${Qt6Widgets_INCLUDE_DIRS}

# 添加头文件目录,实际测试中,不添加好像也没问题
target_include_directories(${PROJECT_NAME} PRIVATE ${Qt6Widgets_INCLUDE_DIRS})
# 链接Qt相关库,其它Qt库也都是这种格式
target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Core Qt6::Widgets)

设置目标属性

主要在Windows和MACOS下起作用

目的是禁用命令行窗口

set_target_properties(
    ${PROJECT_NAME} PROPERTIES
    WIN32_EXECUTABLE ON
    MACOSX_BUNDLE ON
)

问题及解决

首先,安装Qt的时候就应该安装相关依赖

sudo apt-get install build-essential libgl1-mesa-dev
[cmake] -- Could NOT find XKB (missing: XKB_LIBRARY XKB_INCLUDE_DIR) (Required is at least version "0.5.0")
[cmake] -- Could NOT find WrapVulkanHeaders (missing: Vulkan_INCLUDE_DIR)

使用以下命令安装相关依赖

sudo apt install libxkbcommon-dev libvulkan-dev

项目文件结构

.
├── build
├── CMakeLists.txt
├── Demo_en.ts
├── Demo_fr.ts
├── main.cpp
├── MainWindow.cpp
├── MainWindow.h
├── MainWindow.ui
└── README.md

其中ts文件是自动生成在当前目录的

qrc和qm文件以及ui的头文件都生成在了build目录内

源码

CMakeListstxt_251">CMakeLists.txt

cmake_minimum_required(VERSION 3.16)
project("Demo" VERSION 1.0.0 LANGUAGES CXX)

# 设置Qt路径
set(CMAKE_PREFIX_PATH "/opt/Qt/6.5.2/gcc_64;${CMAKE_PREFIX_PATH}")

# 设置C++标准
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 寻找Qt6库以及其中各种模块
find_package(Qt6 REQUIRED COMPONENTS LinguistTools Core Widgets)
# Qt CMake通用设置
qt_standard_project_setup()

# 添加文件到应用程序,这是Qt提供的工具,因此ui文件也可以直接添加进去
# 需要注意,这个ui文件会生成一个ui_xxx.h的头文件
# 不过这个头文件需要在第一次编译之后才会生成,所以构建结束后找不到这个头文件是正常的
qt_add_executable(
    ${PROJECT_NAME}
    main.cpp
    MainWindow.h
    MainWindow.cpp
    MainWindow.ui
)

qt_add_resources(
    ${PROJECT_NAME}
    ${PROJECT_NAME} PREFIX "/" FILES
    README.md
)

qt_add_translations(
    ${PROJECT_NAME}
    TS_FILES
    "${PROJECT_NAME}_en.ts"
    "${PROJECT_NAME}_fr.ts"
)
# qt_add_lupdate(${PROJECT_NAME} TS_FILES "${PROJECT_NAME}_en.ts" "${PROJECT_NAME}_fr.ts")
# qt_add_lrelease(${PROJECT_NAME} TS_FILES "${PROJECT_NAME}_en.ts" "${PROJECT_NAME}_fr.ts")

# 添加头文件目录,实际测试中,不添加好像也没问题
target_include_directories(${PROJECT_NAME} PRIVATE ${Qt6Widgets_INCLUDE_DIRS})
# 链接Qt相关库,其它Qt库也都是这种格式
target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Core Qt6::Widgets)

# 设置应用程序属性,主要在Windows和MACOS下起作用
set_target_properties(
    ${PROJECT_NAME} PROPERTIES
    WIN32_EXECUTABLE ON
    MACOSX_BUNDLE ON
)


MainWindow.h

#ifndef _MAIN_WINDOW_H_
#define _MAIN_WINDOW_H_

#include <QWidget>

namespace Ui {
class uiMainWid;
} // namespace Ui

class MainWindow : public QWidget {
    Q_OBJECT;

public:
    MainWindow(QWidget* parent = nullptr);
    ~MainWindow();

    void onClickSearch();

private:
    Ui::uiMainWid* ui = nullptr;
};

#endif

MainWindow.cpp

#include "MainWindow.h"
#include "ui_MainWindow.h"
#include <QFile>

MainWindow::MainWindow(QWidget* parent)
    : QWidget(parent)
    , ui(new Ui::uiMainWid)
{
    ui->setupUi(this);
    setWindowTitle(MainWindow::tr("羽飞的主页"));

    connect(ui->uiSearchBtn, &QPushButton::clicked, this, &MainWindow::onClickSearch);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::onClickSearch()
{
    QString txt = ui->uiLineEdit->text();
    if (txt.isEmpty()) {
        QFile doc { ":/README.md" };
        bool isOk = doc.open(QIODevice::ReadOnly);
        if (!isOk) {
            ui->uiTxtEdit->setPlainText(MainWindow::tr("文件读取错误"));
            return;
        }
        txt = doc.readAll();
        ui->uiTxtEdit->setPlainText(txt);
    }
}


http://www.niftyadmin.cn/n/5134380.html

相关文章

我的架构复盘

1、背景 我目前公司研发中心担任软件研发负责人&#xff0c;研发中心分为3组&#xff0c;总共有30多人。研发中心主要开发各类生产辅助工具&#xff0c;比如巡检、安全教育等系统。系统不对外&#xff0c;只在公司内部使用。 就我个人来说&#xff0c;作为研发负责人&#xf…

算法笔记【4】-冒泡排序法改进

一、冒泡排序缺点 冒泡排序是一种简单但效率较低的排序算法。冒泡排序通过比较相邻元素并交换位置来实现排序。具体而言&#xff0c;它从数组的第一个元素开始&#xff0c;依次比较相邻的两个元素&#xff0c;如果顺序错误则交换它们的位置&#xff0c;直到整个数组排好序为止…

leetCode 136.只出现一次的数字 + 位运算

136. 只出现一次的数字 - 力扣&#xff08;LeetCode&#xff09; 给你一个 非空 整数数组 nums &#xff0c;除了某个元素只出现一次以外&#xff0c;其余每个元素均出现两次。找出那个只出现了一次的元素。你必须设计并实现线性时间复杂度的算法来解决此问题&#xff0c;且该算…

react怎么实现父子组件传值?

在React中&#xff0c;父组件向子组件传递值可以通过以下几种方法实现&#xff1a; 1.使用Props&#xff1a;父组件将数据通过props属性传递给子组件&#xff0c;在子组件中通过props接收和使用这些值。 // ParentComponent.jsx import React from react; import ChildCompone…

百货中心供应链管理系统

毕业设计说明书 百货中心供应链管理系统 百货中心供应链管理系统 摘要 近年来&#xff0c;随着计算机技术的发展&#xff0c;以及信息化时代下企业对效率的需求&#xff0c;计算机技术与通信技术已经被越来越多地应用到各行各业中去。百货中心作为物流产业链中重要的一环&a…

【JAVA学习笔记】49 - String类,StringBuffer类,StringBuilder类(重要)

项目代码 https://github.com/yinhai1114/Java_Learning_Code/tree/main/IDEA_Chapter13/src/com/yinhai/wrapper_/string_ https://github.com/yinhai1114/Java_Learning_Code/tree/main/IDEA_Chapter13/src/com/yinhai/wrapper_/stringbuffer_ https://github.com/yinhai1114…

工程建筑模板厂家货源,酚醛胶镜面胶合板实用型

作为工程建筑模板厂家&#xff0c;我们提供高品质的酚醛胶镜面胶合板&#xff0c;为建筑行业的模板需求提供可靠的货源。我们的产品以实用型为设计理念&#xff0c;旨在满足各类工程的施工需求并提供出色的性能。我们的酚醛胶镜面胶合板采用优质的木材作为原材料&#xff0c;经…

白嫖的安信可-小安派s1开发板开箱

白嫖的安信可-小安派s1开发板开箱 前言1、主板2、SPI触摸屏3、DVP摄像头4、喇叭5、咪头 前言 今天是了解到接触到在到白嫖&#xff0c;拿到小安派的第二天&#xff0c;那就介绍一下刚刚接触的小安派。看到开发文档的烧录硬件的要求&#xff0c;安信可官方有烧录软件&#xff0…