Qml基础概念
# 01.Qml基础概念
# 目录介绍
- 1.1 QT技术介绍
- 1.1.1 什么是QT
- 1.1.2 支持平台
- 1.1.3 QT的版本
- 1.1.4 下载与安装
- 1.2 QT框架安装
- 1.2.1 QT核心模块
- 1.2.2 安装QT框架
- 1.2.3 开发须知
- 1.2.4 检查QT环境
- 1.3 IDE工具安装
- 1.3.1 IDE开发环境
- 1.3.2 Creator介绍
- 1.4 开发Widget项目
- 1.4.1 环境准备
- 1.4.2 创建项目
- 1.4.3 编写代码
- 1.4.4 运行程序
- 1.4.5 代码解析
- 1.4.6 扩展功能
- 1.5 Quick介绍
- 1.5.1 Quick概念
- 1.5.2 Quick模块
- 1.5.3 Quick优势
- 1.5.4 Quick技术
- 1.5.5 Quick程序发布
- 1.6 开发Quick项目
- 1.6.1 创建Quick项目
- 1.6.2 编写QML代码
- 1.6.3 load加载页面
- 1.6.4 拓展功能
- 1.6.5 CMakeList
- 1.6.6 添加图片资源
- 1.7 程序main入口
- 1.7.1 程序入口代码
- 1.7.2 入口代码设计
- 1.7.3 QGuiApplication
- 1.7.4 QQmlApplicationEngine
- 1.7.5 QQmlContext
- 1.7.6 QQmlComponent
- 1.7.6 入口功能
- 1.7.7 注意事项
- 1.7.8 可能的扩展
# 1.1 QT技术介绍说明
在 Linux 环境下使用 Qt 进行开发是一种非常流行的选择,因为 Qt 是一个功能强大的跨平台 C++ 框架,支持 GUI 开发、网络编程、数据库操作等。
# 1.1.1 什么是QT
Qt是一个跨平台的C++图形用户界面应用程序框架。它为应用程序开发者提供建立艺术级图形界面所需的所有功能。它是完全面向对象的,很容易扩展,并且允许真正的组件编程。
# 1.1.2 支持平台
- Windows – XP、Vista、Win7、Win8、Win2008、Win10
- Uinux/X11 – Linux、Sun Solaris、HP-UX、Compaq Tru64 UNIX、IBM AIX、SGI IRIX、FreeBSD、BSD/OS、和其他很多X11平台
- Macintosh – Mac OS X
- Embedded – 有帧缓冲支持的嵌入式Linux平台,Windows CE
# 1.1.3 QT的版本
商业版:为商业软件提供开发,他们提供传统商业软件发行版,并且提供在商业有效期内的免费升级和技术支持服务。
开源的LGPL版本:为了开发自有而设计的开放源码软件,它提供了和商业版本同样的功能,在GNU通用公共许可下,它是免费的。
# 1.1.4 下载与安装
下载地址:http://www.qt.io/download-open-source/
# 1.2 QT框架安装
# 1.2.1 QT核心模块
Qt 提供了丰富的模块,以下是一些常用的模块:
| 模块名称 | 功能描述 |
|---|---|
| Qt Core | 核心功能(如信号槽、事件循环等) |
| Qt GUI | 图形用户界面基础 |
| Qt Widgets | 提供丰富的 UI 控件 |
| Qt Network | 网络编程支持 |
| Qt SQL | 数据库操作 |
| Qt Multimedia | 多媒体支持 |
| Qt WebEngine | 嵌入 Web 内容 |
# 1.2.2 安装QT框架
qt-opensource-mac-x64-5.12.9 (opens new window),是什么:
这是 Qt 框架 的一个版本,具体是 Qt 5.12.9,适用于 macOS(x64 架构)。是开发 Qt 应用程序的基础,提供了核心库和工具。
Qt 是一个跨平台的 C++ 应用程序框架,用于开发图形用户界面(GUI)和非 GUI 程序。包含内容:
- Qt 核心库(如 QtCore、QtGui、QtWidgets 等)。
- Qt 模块(如 QtNetwork、QtSql、QtWebEngine 等)。
- 工具链(如 qmake、Qt Designer、Qt Linguist 等)。
- 文档和示例代码。
用途:用于开发和运行基于 Qt 的应用程序。开发者可以使用 Qt 框架编写跨平台的 C++ 程序。
# 1.2.3 开发须知
Qt 框架 是开发 Qt 应用程序的基础,提供了核心库和工具。
Qt Creator 是一个 IDE,用于更方便地开发基于 Qt 框架的应用程序。
通常情况下,开发者需要同时安装 Qt 框架 和 Qt Creator,因为 Qt Creator 依赖于 Qt 框架来编译和运行程序。
# 1.2.4 检查QT环境
qmake 是 Qt 的构建工具,用于生成 Makefile。验证 qmake 是否安装成功:
# 1.3 IDE工具安装
# 1.3.1 IDE开发环境
1.CLion(跨平台,基于 CMake)
CLion 是 JetBrains 开发的跨平台 C++ IDE,支持 Qt 开发(基于 CMake)。
配置 Qt 环境: 在 CLion 中打开 File > Settings > Build, Execution, Deployment > CMake。
2.VSCode(轻量级,插件支持)
VSCode 是微软开发的轻量级代码编辑器,通过插件支持 Qt 开发。
安装 Qt 插件:打开 VSCode,进入 Extensions,搜索并安装以下插件:C/C++:提供 C++ 语言支持。CMake Tools:支持 CMake 构建系统。Qt Tools:提供 Qt 开发支持。
配置 Qt 环境:在 VSCode 中配置 CMake 和 Qt 路径。
# 1.3.2 Creator介绍
Qt Creator(官方推荐)
Qt Creator 是 Qt 官方提供的跨平台 IDE,专为 Qt 开发设计,功能强大且易于使用。
访问 Qt 官方网站 (opens new window) 下载 Qt 安装程序。在安装过程中选择 Qt Creator 和所需的 Qt 版本。
- 支持跨平台(Windows、macOS、Linux)。
- 内置 Qt 设计器,支持可视化 UI 设计。
- 集成调试器、代码编辑器、版本控制工具。
- 支持 CMake、QMake 等多种构建系统。
用途:用于编写、调试和构建基于 Qt 的应用程序。Qt Creator 提供了丰富的工具和功能,简化了 Qt 开发流程。
# 1.4 第一个程序
在 Qt 中编写第一个学习程序通常是一个简单的 Hello World 应用程序。以下是一个完整的步骤,帮助你创建一个基本的 Qt 程序。
# 1.4.1 环境准备
确保你已经安装了以下工具:
Qt 框架(如 qt-opensource-mac-x64-5.12.9)。
Qt Creator(如 qt-creator-opensource-mac-x86_64-17.0.0)。
# 1.4.2 创建项目
- 打开 Qt Creator。
- 点击 New Project。
- 选择 Application -> Qt Widgets Application,然后点击 Choose。
- 设置项目名称(如
HelloWorld)和保存路径,点击 Next。 - 选择构建工具(默认使用
qmake),点击 Next。 - 选择 Qt 版本(如
Qt 5.12.9),点击 Next。 - 点击 Finish 完成项目创建。
# 1.4.3 编写代码
- 在 Qt Creator 中,打开
main.cpp文件(位于Sources目录下)。 - 修改
main.cpp文件的内容如下:
#include <QApplication>
#include <QLabel>
int main(int argc, char *argv[]) {
// 创建应用程序对象
QApplication app(argc, argv);
// 创建一个标签控件,显示 "Hello, Qt!"
QLabel label("Hello, Qt!");
// 设置标签的字体和大小
label.setFont(QFont("Arial", 24));
// 显示标签
label.show();
// 进入事件循环
return app.exec();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 1.4.4 运行程序
- 点击 Run 按钮(绿色三角形图标)。
- 如果一切正常,程序会弹出一个窗口,显示 "Hello, Qt!"。
# 1.4.5 代码解析
Qt系统提供的标准类名声明头文件没有.h后缀
Qt一个类对应一个头文件,类名就是头文件名
QApplication应用程序类
- 管理图形用户界面应用程序的控制流和主要设置。
- 是Qt的整个后台管理的命脉它包含主事件循环,在其中来自窗口系统和其它资源的所有事件处理和调度。它也处理应用程序的初始化和结束,并且提供对话管理。
- 对于任何一个使用Qt的图形用户界面应用程序,都正好存在一个QApplication 对象,而不论这个应用程序在同一时间内是不是有0、1、2或更多个窗口。
app.exec() 程序进入消息循环,等待对用户输入进行响应。
这里main()把控制权转交给Qt,Qt完成事件处理工作,当应用程序退出的时候exec()的值就会返回。
在exec()中,Qt接受并处理用户和系统的事件并且把它们传递给适当的窗口部件。
# 1.4.6 扩展功能
你可以进一步扩展这个程序,例如:
添加按钮控件:
#include <QPushButton>
QPushButton *button = new QPushButton("Click Me", &label);
QObject::connect(button, &QPushButton::clicked, []() {
qDebug() << "Button clicked!";
});
2
3
4
5
6
使用布局管理器:
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(&label);
layout->addWidget(button);
QWidget window;
window.setLayout(layout);
window.show();
2
3
4
5
6
7
# 1.5 Quick介绍
# 1.5.1 Quick概念
Qt Quick 是 Qt 框架中用于构建现代用户界面(UI)的技术,基于声明式语言 QML(Qt Meta-Object Language)。
它专注于快速开发流畅、动态的 UI,特别适合移动应用、嵌入式设备和桌面应用。
# 1.5.2 Quick模块
核心模块:QtQuick 是 Qt Quick 的核心模块,提供了基本的 UI 元素(如 Rectangle、Text、Image 等)和布局功能。
其他模块:
QtQuick.Controls:提供高级 UI 控件(如按钮、滑块、列表等)。QtQuick.Layouts:提供布局管理器(如RowLayout、ColumnLayout)。QtQuick.Dialogs:提供对话框(如文件选择器、颜色选择器)。QtQuick.VirtualKeyboard:提供虚拟键盘支持。
# 1.5.3 Quick优势
- 快速开发:声明式语法和丰富的 UI 元素加速开发。
- 跨平台:支持 Windows、macOS、Linux、Android、iOS 等平台。
- 高性能:基于 OpenGL 渲染,适合高性能 UI。
- 动态性:支持动态绑定和实时更新。
# 1.5.4 Quick技术
主要会涉及到集中技术:
- QML:用户界面的标记语言
- javaScript:动态脚本语言
- QT C++:高度可移植的增强型C++库
# 1.6 开发Quick项目
创建一个 Qt Quick 项目并编写一个简单的 Hello World 程序,可以按照以下步骤进行。
Qt Quick 是基于 QML(Qt Meta-Object Language)的声明式框架,适合开发现代、动态的 UI。
# 1.6.1 创建Quick项目
- 打开 Qt Creator。
- 点击 New Project。
- 选择 Application -> Qt Quick Application - Empty,然后点击 Choose。
- 设置项目名称(如
HelloWorldQuick)和保存路径,点击 Next。 - 选择构建工具(默认使用
qmake),点击 Next。 - 选择 Qt 版本(如
Qt 5.12.9),点击 Next。 - 点击 Finish 完成项目创建。
# 1.6.2 编写QML代码
- 在 Qt Creator 中,打开
main.qml文件(位于Sources目录下)。 - 修改
main.qml文件的内容如下:
import QtQuick 2.12
import QtQuick.Window 2.12
Window {
visible: true
width: 640
height: 480
title: "Hello World"
// 添加一个文本控件
Text {
text: "Hello, Qt Quick!"
anchors.centerIn: parent
font.pixelSize: 24
color: "blue"
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 1.6.3 load加载页面
在main.cpp代码中:
int main(int argc, char *argv[]) {
// 加载页面
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
2
3
4
5
当调用 engine.load(QUrl("qrc:/qml/main.qml")) 时:
- URL解析: Qt识别 qrc: 协议,知道这是资源文件请求
- 路径映射: /qml/main.qml 映射到资源系统中的对应文件
- 资源查找: 在编译时嵌入的资源数据中查找该文件
- 内存加载: 直接从内存中读取文件内容(不需要磁盘I/O)
- QML解析: QML引擎解析文件内容并创建对象树
# 1.6.4 拓展功能
添加按钮控件:
Button {
text: "Click Me"
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
onClicked: {
console.log("Button clicked!");
}
}
2
3
4
5
6
7
8
注意:需要导入 QtQuick.Controls 2.12 模块:
import QtQuick.Controls 2.12
# 1.6.5 CMakeList
CMakeLists.txt 通过这个文件,CMake 可以正确配置和构建你的 Qt Quick 应用程序。
- 项目名称、版本和语言。
- Qt 模块的查找和加载。
- 可执行文件的定义和 QML 模块的添加。
- 目标属性的设置(如 macOS 和 Windows 的构建选项)。
- Qt 库的链接。
- 安装规则的定义。
# 指定了 CMake 的最低版本要求为 3.16。
cmake_minimum_required(VERSION 3.16)
# 定义了项目名称为 QuickApp,版本号为 0.1,使用的编程语言为 C++。
project(QuickApp VERSION 0.1 LANGUAGES CXX)
# 设置要求使用 C++ 标准。
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 查找并要求 Qt6 中的 Quick 模块。
find_package(Qt6 REQUIRED COMPONENTS Quick)
# 设置 Qt 项目的标准配置,要求 Qt 版本为 6.8。
qt_standard_project_setup(REQUIRES 6.8)
# 添加一个名为 appQuickApp 的可执行文件,其中包含 main.cpp 文件。
qt_add_executable(appQuickApp
main.cpp
)
# 添加一个 QML 模块到 appQuickApp 可执行文件中,指定 URI 为 QuickApp,版本为 1.0,包含的 QML 文件为 Main.qml。
qt_add_qml_module(appQuickApp
URI QuickApp
VERSION 1.0
QML_FILES
Main.qml
)
# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
# If you are developing for iOS or macOS you should consider setting an
# explicit, fixed bundle identifier manually though.
# 设置 appQuickApp 目标的属性,包括 macOS 下的 Bundle 版本、短版本号、是否为 Bundle 应用,以及是否为 Windows 下的可执行文件。
set_target_properties(appQuickApp PROPERTIES
# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appQuickApp
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE
)
# 将 Qt6 中的 Quick 模块链接到 appQuickApp 目标中。
target_link_libraries(appQuickApp
PRIVATE Qt6::Quick
)
# 包含 GNUInstallDirs 模块,用于设置安装目录。
include(GNUInstallDirs)
# 安装 appQuickApp 目标,将可执行文件安装到当前目录,库文件安装到指定的库目录,运行时文件安装到指定的二进制目录。
install(TARGETS appQuickApp
BUNDLE DESTINATION .
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# 1.6.6 添加图片资源
打开 .qrc 文件。在 Projects 视图中,双击 .qrc 文件(例如 resources.qrc)。
- 在
.qrc文件编辑器中,点击 Add -> Add Files。 - 选择要添加的图片文件(如
logo.png)。图片会被添加到.qrc文件中,并生成一个资源路径(如:/images/logo.png)。
设置资源前缀(可选)
- 在
.qrc文件编辑器中,可以点击 Add -> Add Prefix 创建一个前缀(如/images),然后将图片文件移动到该前缀下。 - 这样图片的资源路径会变成
:/images/logo.png。
在 QML 中,可以使用 Image 组件加载图片资源。例如:
Image {
source: "qrc:/images/logo.png" // 资源路径
anchors.centerIn: parent
width: 200
height: 200
fillMode: Image.PreserveAspectFit
}
2
3
4
5
6
7
# 1.7 程序main入口
# 1.7.1 程序入口代码
该代码的主要作用是启动一个基于Qt Quick的应用程序。它负责初始化应用程序引擎,加载QML文件(通常是主界面),并启动应用程序的事件循环。
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[]) {
//启用高DPI屏幕缩放支持。需在创建QGuiApplication前调用。
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
//初始化Qt GUI框架。管理应用程序事件循环、全局配置等核心功能。
//使用QGuiApplication(而非QApplication)表示这是一个无原生控件的纯QML界面应用。
QGuiApplication app(argc, argv);
//创建QML引擎实例。解析QML文件、绑定JavaScript上下文、管理QML对象树生命周期。
QQmlApplicationEngine engine;
//加载QML入口文件。
//qrc:/: 从Qt资源系统(*.qrc编译生成的二进制资源)中读取文件。
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
//检查QML是否成功加载。
if (engine.rootObjects().isEmpty()) {
//后果:直接退出程序,避免空界面。
return -1;
}
//启动Qt事件循环。
//阻塞等待用户输入、定时器、网络事件等,直到应用退出。
//事件循环结束后返回退出代码(通常为0)。
return app.exec();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 1.7.2 入口代码设计
- 入口函数:标准的C++ main函数。
- 初始化:首先设置应用程序属性(启用高DPI缩放),然后创建QGuiApplication实例。
- 引擎创建:创建QQmlApplicationEngine对象,该对象用于加载和运行QML文件。
- 加载QML:从资源系统(qrc)加载名为main.qml的QML文件。
- 错误处理:检查QML文件加载后是否创建了任何根对象(即QML是否成功加载),如果根对象为空则返回错误。
- 事件循环:最后调用app.exec()进入主事件循环。
# 1.7.3 QGuiApplication
QGuiApplication:管理GUI应用程序的控制流和主要设置。它处理事件循环,是整个应用程序的核心。
QGuiApplication 是 Qt 框架中的一个核心类,它是所有基于 Qt GUI 的应用程序的入口点,负责初始化应用程序、处理事件循环以及管理窗口和屏幕等资源。它的主要功能包括:
- 初始化应用程序:设置应用程序的基本环境,如字体、调色板、屏幕等。
- 事件循环:管理事件队列,处理用户输入、窗口事件、定时器等。
- 窗口管理:管理应用程序的窗口和屏幕。
- 资源管理:管理应用程序的资源,如字体、图标、样式等。
- 退出机制:提供应用程序的退出和清理功能。
QGuiApplication的工作原理
(1) 初始化,QGuiApplication 在构造函数中完成以下初始化工作:
- 设置应用程序的名称、版本等元信息。
- 初始化 GUI 相关的子系统,如字体、调色板、屏幕等。
- 解析命令行参数,处理与 GUI 相关的选项(如窗口大小、位置等)。
(2) 事件循环
QGuiApplication的核心是事件循环(Event Loop),通过exec()方法启动。- 事件循环不断从事件队列中获取事件(如鼠标点击、键盘输入、窗口事件等),并将其分发给相应的对象(如窗口、控件等)进行处理。
- 事件循环还负责处理定时器、网络事件等其他异步操作。
(3) 窗口管理
QGuiApplication管理应用程序的所有窗口(QWindow实例)。- 它负责窗口的创建、显示、隐藏、关闭等操作。
- 它还处理与屏幕相关的逻辑,如多屏幕支持、屏幕分辨率变化等。
(4) 资源管理
QGuiApplication管理应用程序的共享资源,如字体、图标、样式等。- 它提供了统一的接口来加载和使用这些资源。
(5) 退出机制
- 当调用
QGuiApplication::quit()或最后一个窗口关闭时,QGuiApplication会退出事件循环并清理资源。 - 在退出前,它会触发
aboutToQuit()信号,允许应用程序执行清理操作。
QGuiApplication的主要功能
(1) 事件处理
QGuiApplication提供了事件过滤器(Event Filter)和事件处理器(Event Handler)机制,允许开发者拦截和处理特定事件。例如,可以重写QGuiApplication::event()方法来处理自定义事件。
(2) 多屏幕支持
QGuiApplication提供了对多屏幕的支持,可以通过screens()方法获取所有屏幕的信息。它还处理屏幕的动态变化(如屏幕分辨率调整、屏幕添加或移除)。
(3) 样式与主题
QGuiApplication管理应用程序的样式和主题,可以通过setStyle()方法设置应用程序的样式(如 Fusion、Windows 等)。它还支持自定义样式和主题。
(4) 国际化
QGuiApplication支持国际化(i18n),可以通过installTranslator()方法加载翻译文件。它还提供了与语言和区域设置相关的功能。
QGuiApplication与QApplication的区别
QGuiApplication是QApplication的轻量级版本,专门用于不需要完整 Widget 支持的 GUI 应用程序(如基于 QML 的应用程序)。QApplication提供了更多的功能,如完整的 Widget 支持、菜单、工具栏等,适用于传统的桌面应用程序。- 如果应用程序仅使用 QML 而不使用 Widget,建议使用
QGuiApplication,以减少内存占用和启动时间。
# 1.7.4 QQmlApplicationEngine
QQmlApplicationEngine 是 Qt 框架中的一个核心类,用于加载和运行 QML 应用程序。它是 QML 引擎的封装,提供了简单易用的接口来加载 QML 文件并管理应用程序的生命周期。
1. 作用,
QQmlApplicationEngine的主要作用包括:
- 加载 QML 文件:将 QML 文件加载到应用程序中,并创建对应的 QML 对象树。
- 管理应用程序生命周期:自动管理 QML 对象的创建、初始化和销毁。
- 提供上下文环境:为 QML 对象提供上下文(
QQmlContext),支持数据绑定和 C++ 与 QML 的交互。 - 简化 QML 应用程序开发:通过封装底层细节,简化 QML 应用程序的启动和运行。
2. 使用方法,
QQmlApplicationEngine的使用非常简单,通常用于启动一个 QML 应用程序。以下是基本的使用步骤:
(1) 包含头文件
#include <QGuiApplication>
#include <QQmlApplicationEngine>
2
(2) 创建应用程序对象
QGuiApplication app(argc, argv);
(3) 创建 QML 引擎并加载 QML 文件
QQmlApplicationEngine engine;
engine.load(QUrl("qrc:/main.qml")); // 加载 QML 文件
2
(4) 运行应用程序
return app.exec();
3. 原理,
QQmlApplicationEngine的工作原理基于以下核心概念:
(1) QML 引擎
QQmlApplicationEngine 是 QQmlEngine 的子类,封装了 QML 引擎的功能。QML 引擎负责解析 QML 文件、创建 QML 对象树、处理数据绑定和信号槽机制。
(2) 上下文环境
QQmlApplicationEngine 为 QML 对象提供了一个根上下文(rootContext),可以通过 engine.rootContext() 访问。上下文用于管理 QML 对象的可见属性和数据绑定。
(3) 对象树管理
QQmlApplicationEngine 自动管理 QML 对象的生命周期。当 QML 文件加载时,引擎会创建对应的对象树,并在应用程序退出时销毁这些对象。
(4) 信号槽机制
QQmlApplicationEngine 支持 QML 和 C++ 之间的信号槽通信。可以通过 QObject::connect 将 C++ 信号连接到 QML 槽,或者将 QML 信号连接到 C++ 槽。
# 1.7.5 QQmlContext
QQmlContext 是 Qt QML 框架中的一个核心类,用于管理 QML 对象的上下文环境。它在 QML 和 C++ 交互、数据绑定、作用域管理等方面起着重要作用。
QQmlContext 是 QML 框架中用于管理上下文环境的核心类,主要作用包括:
- 将 C++ 对象暴露给 QML。
- 管理 QML 对象的作用域和生命周期。
- 实现组件隔离和动态加载。
1.作用:
QQmlContext的主要作用是为 QML 对象提供一个上下文环境,用于:
- 数据绑定:将 C++ 对象或数据暴露给 QML,实现数据驱动 UI。
- 作用域管理:定义 QML 对象的作用域,控制变量的可见性和生命周期。
- 组件隔离:为不同的 QML 组件提供独立的上下文,避免命名冲突。
- 动态加载:在运行时动态创建和加载 QML 组件,并为其提供上下文。
2. 用途,
QQmlContext的常见用途包括:
(1) 将 C++ 对象暴露给 QML,通过 QQmlContext::setContextProperty,可以将 C++ 对象或数据暴露给 QML,使 QML 可以直接访问这些对象。
// C++ 代码
QQuickView view;
QQmlContext* context = view.rootContext();
context->setContextProperty("myObject", myCppObject);
view.setSource(QUrl("qrc:/main.qml"));
view.show();
2
3
4
5
6
// QML 代码
Text {
text: myObject.someProperty // 访问 C++ 对象的属性
}
2
3
4
(2) 动态创建 QML 组件,通过 QQmlComponent 和 QQmlContext,可以在运行时动态创建 QML 组件,并为其提供上下文。
QQmlEngine engine;
QQmlComponent component(&engine, QUrl("qrc:/MyComponent.qml"));
QQmlContext* context = new QQmlContext(engine.rootContext());
context->setContextProperty("myData", someData);
QObject* object = component.create(context);
2
3
4
5
管理 QML 对象的作用域,QQmlContext 可以定义 QML 对象的作用域,控制变量的可见性和生命周期。
QQmlEngine engine;
QQmlComponent component(&engine, QUrl("qrc:/MyComponent.qml"));
QQmlContext* context = new QQmlContext(engine.rootContext());
context->setContextProperty("localVariable", 42);
QObject* object = component.create(context);
2
3
4
5
实现组件隔离,通过为不同的 QML 组件创建独立的 QQmlContext,可以避免命名冲突。
QQmlEngine engine;
QQmlComponent component1(&engine, QUrl("qrc:/Component1.qml"));
QQmlComponent component2(&engine, QUrl("qrc:/Component2.qml"));
QQmlContext* context1 = new QQmlContext(engine.rootContext());
context1->setContextProperty("data", data1);
QQmlContext* context2 = new QQmlContext(engine.rootContext());
context2->setContextProperty("data", data2);
QObject* object1 = component1.create(context1);
QObject* object2 = component2.create(context2);
2
3
4
5
6
7
8
9
10
11
12
3. 原理,
QQmlContext的工作原理基于以下核心概念:
(1) 上下文树
QQmlContext 是一个树形结构,每个 QQmlContext 都有一个父上下文(除了根上下文)。QML 对象在查找变量或属性时,会沿着上下文树向上查找,直到找到匹配的变量或到达根上下文。
- 根上下文:由
QQmlEngine创建,是上下文树的根节点。 - 子上下文:通过
new QQmlContext(parentContext)创建,继承父上下文的属性。
(2) 数据绑定
QQmlContext 通过 setContextProperty 将 C++ 对象或数据暴露给 QML。QML 引擎会在上下文中查找这些属性,并将其绑定到 QML 对象。
(3) 作用域链
QML 对象在访问变量时,会按照以下顺序查找:
- 当前对象的属性。
- 当前对象的上下文(
QQmlContext)。 - 父对象的上下文,直到根上下文。
(4) 生命周期管理
QQmlContext 的生命周期由其父上下文或 QQmlEngine 管理。当上下文被销毁时,其绑定的 QML 对象也会被销毁。
# 1.7.6 入口功能
- 启动一个Qt Quick应用程序。
- 启用高DPI缩放支持,以适配高分辨率屏幕。
- 从资源文件加载QML界面。
- 如果QML加载失败(例如,文件不存在或QML代码有错误),则应用程序立即退出并返回错误代码。
- 如果加载成功,则进入事件循环,处理用户输入、定时器事件等。
# 1.7.7 注意事项
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); 这行代码应该在创建QGuiApplication实例之前调用,以确保在应用程序初始化时生效。
QQmlApplicationEngine 的load方法加载一个QML文件,该文件必须包含一个顶级Item(如Window或ApplicationWindow),因为QQmlApplicationEngine会将该顶级项显示出来。
如果QML加载成功,engine.rootObjects()会返回一个非空的QObjectList(至少包含一个根对象,即QML中定义的最外层对象);如果为空,说明加载失败。
# 1.7.8 可能的扩展
在调用engine.load之前,可以设置上下文属性(engine.rootContext()->setContextProperty(...))将C++对象暴露给QML。
可以在加载QML之后,通过engine.rootObjects()[0]获取QML根对象,进行进一步的操作(如调用方法、设置属性等)。