Qt6 学习指南:前言+安装基本依赖
前言
在 Window 下使用 Qt 开发时,我们常常使用 Qt 官方的集成开发环境。在这个专栏里,我将探索一条在 linux 脱离集成开发环境的开发路线,着重于 qt c++ 结合 qml 的开发模式。由于是现学现卖,更新较慢,偶有错误,请大家悉心指正。废话少说,进入正题。
相关链接
第一章:环境配置
- 安装基本依赖
- 项目的文件结构
- cmake 构建工程
- vscode 基本配置
- 常见问题汇总
安装基本依赖
- OS:ubuntu22.04
- toolkit:gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
- cmake:3.22.1
- ninja:1.10.1
- vscode:1.99.3
- qt:6.9.0
温馨提示:
对于一个合格的开发者,了解自己的环境很重要。一是便于您查阅相关的 document,二是如果您想找别人帮忙修复 bug,首先您就要提供相关环境信息。
如何获取自己的环境信息?您需要有本的 linux 经验。
ubuntu 下安装基本依赖和工具:
apt install -y \# Basic build toolsbuild-essential \cmake \ninja-build \# Qt6 libraries (1,2,3 required 4optional)qt6-base-dev \qt6-declarative-dev \qml6-module-qtquick-controls \qml-qt6# others(1 required 2,3 optional)libgl1-mesa-dev \git \vim \
简单介绍一下这里安装的东西:
qt6-base-dev
提供 Qt 核心库,如:QtCore, QtGui, QtWidgets, QtNetwork
qt6-declarative-dev
提供声明式 UI 相关支持,如:QML 引擎,UI 框架等
qml6-module-qtquick-controls
主要提供 QtQuick UI 控件库
qml-qt6
主要包含 qml 命令,用来调试 .qml 文件
安装 vscode:
传送门
上一节:前言
下一节:项目的文件结构
项目的文件结构
为了便于学习和管理代码,我们需要设计一个良好的文件结构。
其中应该包含:
- 项目构建文件:
CMakeLists.txt
- 路径管理文件:
.qrc
- cpp 源文件:
cpp/
- qml 源文件:
qml/
- 资源文件夹:
asserts/
- 文档文件夹:
docs/
- 构建目录:
build/
温馨提示:
docs\
不是必要的,但是您最好拥有它,因为您需要养成良好的项目记录习惯,已经通过 README.md 介绍你的项目的习惯。
通常建议使用 markdown 进行文档编写,强推 typora(收费),次之 obsidian(免费),也可以用 vscode 插件(免费,后面介绍)
build\
由 cmake 管理,这里你可以不要自己创建
MyQtApp/
│── CMakeLists.txt # CMake build file
│── .qrc # Qt path management file
│
├── 📁 cpp/ # C++ source files
│ │── main.cc # Example C++ backend class
│ └── main.hh # Another C++ class
├── 📁 cmake/ # .cmake file
│ │── install.cmake # manage install
│ └── compiler.cmake # manage compiler feather
│
├── 📁 qml/ # QML UI components
│ │── main.qml # Main window QML file
│ │── Components/ # Custom QML components
│ │ └── Button.qml # Example reusable button
│ └── Styles.qml # Global UI styles
│
├── 📁 assets/ # Images, icons, fonts
│ ├── icons/ # SVG or PNG icons
│ ├── fonts/ # Custom fonts
│ └── images/ # Backgrounds, logos, etc.
│
├── 📁 build/ # Build output (ignored by Git)
└── 📁 docs/ # Documentation
这是一个比较适合与日常学习以及基础开发的文件结构。
上一节:项目的文件结构
下一节:cmake 构建工程
cmake构建工程
单纯有目录结构是无法编译成可执行的 exe 文件的,这一节就是学习如何将各个目录有机结合,并知道编译器产出可执行文件
先不解释原因,直接把以下内容复制到对应的 cmake 配置文件里去吧。
CMakeList.txt
include(cmake/compiler.cmake)# 项目设置
cmake_minimum_required(VERSION 3.22)
set(CMAKE_POLICY_DEFAULT_CMP0069 NEW)
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
project(stutterview CXX)
set(APP_NAME ${PROJECT_NAME})# 可执行文件和链接库输出路径
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
set(CMAKE_INSTALL_PREFIX /usr/local)message(STATUS "Project name: ${PROJECT_NAME}")
message(STATUS "APP name: ${APP_NAME}")
message(STATUS "Exe output dir: ${CMAKE_SOURCE_DIR}/bin")
message(STATUS "Lib output dir: ${CMAKE_SOURCE_DIR}/lib")
message(STATUS "Default install prefix: ${CMAKE_INSTALL_PREFIX}")# 文件搜索路径
file(GLOB CPP_SOURCES${CMAKE_SOURCE_DIR}/cpp/*.cc
)file(GLOB QML_SOURCES${CMAKE_SOURCE_DIR}/qml/*.qml
)file(GLOB QRC_SOURCES${CMAKE_SOURCE_DIR}/.qrc
)set(HEADERS ${CMAKE_SOURCE_DIR}/cpp
)# set(
# TS_FILES i18n/${APP_NAME}_zh_CN.ts
# )message(STATUS "CPP_SOURCE: ${CPP_SOURCES}")
message(STATUS "QML_SOURCES: ${QML_SOURCES}")
message(STATUS "QRC_SOURCES: ${QRC_SOURCES}")
message(STATUS "HEADERS: ${HEADERS}")
# message(STATUS "TS_FILES: ${TS_FILES}")# 其它中间件支持(一般要做错误检测)
## QmlMaterial
include(middlewares/QmlMaterial/vendor.cmake)
add_definitions("-DQPM_INIT\\(E\\)=E.addImportPath\\(QStringLiteral\\(\\\"qrc:/\\\"\\)\\)\\;")
if(NOT VENDOR_SOURCES STREQUAL "")message(STATUS "VENDOR_SOURCES found! QmlMaterial support enabled")
else()message(STATUS "VENDOR_SOURCES not found! QmlMaterial support disabled")
endif()# Qt 配置
#【TAG】:一些不知道是什么的东西
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)set(Qt6_DIR "/usr/lib/x86_64-linux-gnu/cmake/Qt6/")find_package(Qt6 REQUIREDCOMPONENTSQuick Core Qml Widgets Gui
)
message(STATUS "Qt6_FOUND ${Qt6_FOUND}")## 项目构建
if(QT_KNOWN_POLICY_QTP0004)qt_policy(SET QTP0004 NEW)
endif()qt_add_executable(${APP_NAME}${CPP_SOURCES}${QRC_SOURCES}# ${VENDOR_SOURCES} # QmlMaterial support
)
qt_add_qml_module(${APP_NAME}URI mod VERSION 1.0QML_FILES${QML_SOURCES}RESOURCE_PREFIX /
)
# qt_add_resources(${APP_NAME} _RESOURCES
# BASE qml PREFIX / FILES
# )
# qt_add_translations(${APP_NAME}
# TS_FILES
# ${TS_FILES}
# )
# qt_import_qml_plugins(${APP_NAME})# 局部编译行为设置
target_link_libraries(${APP_NAME}PRIVATEQt6::QuickQt6::WidgetsQt6::QmlQt6::CoreQt6::Gui
)# if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
# target_link_libraries(${APP_NAME}
# PRIVATE
# )
# endif()
# target_include_directories(${APP_NAME} PUBLIC
# ${HEADERS}
# )
# target_compile_definitions(${APP_NAME} PUBLIC -DNDEBUG)
# target_compile_options(${APP_NAME} PRIVATE -Wall -Wextra -Wpedantic -O3)# 输出compilercommand.json
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# 后处理
include(cmake/install.cmake)
install.cmake
install(TARGETS ${APP_NAME}LIBRARY DESTINATION lib # 动态库安装路径ARCHIVE DESTINATION lib # 静态库安装路径RUNTIME DESTINATION bin # 可执行文件安装路径PUBLIC_HEADER DESTINATION include # 头文件安装路径)
compiler.cmake
# 编译器设置(必需在 project 之前)
set(CMAKE_CXX_COMPILER /usr/bin/g++)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 20)#【TAG】:不理解, 启用 LTO
if(CMAKE_BUILD_TYPE AND (CMAKE_BUILD_TYPE STREQUAL "Release"))include(CheckIPOSupported)check_ipo_supported(RESULT _IPO_SUPPORTED OUTPUT ipo_err)if(_IPO_SUPPORTED)message(STATUS "Checking if LTO is supported - Success")set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)endif()
endif()#【TAG】:不理解, 禁用 exceptions 和 rtti
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")string(REGEX REPLACE "/EH[a-z]+" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHs-c-")add_definitions(-D_HAS_EXCEPTIONS=0)string(REGEX REPLACE "/GR" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR-")
else(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")string(REGEX REPLACE "-fexceptions" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions")string(REGEX REPLACE "-frtti" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
endif()message(STATUS "CXX COMPILER: ${CMAKE_CXX_COMPILER}")
message(STATUS "CXX_STANDARD: ${CMAKE_CXX_STANDARD}")
message(STATUS "CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
恭喜你,完成了项目构建的配置任务,但是别急着编译,还没有写 cpp qml 呢。
温馨提示:
初学者不要试图理解这些配置文件的含义,先跟着操作就行,否则很容易进入一种发散式学习状态,该学的没学到。所以先使用别人的轮子,用的过程中再慢慢理解吧。
由于每个人的电脑环境不同,或者对一些地方的理解不到位,或者前面的部分步骤出错,会导致这里在编译时出错。
先别急着改配置文件,在评论区里 @ 我或关注后面的常见问题汇总,并附上 cmake 输出 log 和 ninja 输出 log(详见终端),我们一同解决问题。