Qt6 - QML 与 C++ 联合编程之一

Qt 安装说明

从 Qt 官网 下载在线安装器(比如 qt-online-installer-windows-x64-4.11.0.exe),运行后根据实际开发需求选择相应的组件进行安装。常见组件及其作用如下表所示:

组件作用必选
Qt SDK 包含 Qt 库及相关开发组件,用于开发 Qt 应用程序。是
MinGWWindows 平台上的 GCC 编译器工具链,用于编译 C/C++ 程序。否(使用 MinGW 工具链时必选)
MSVC 微软 C/C++ 编译器工具链,用于 Windows 平台上的 C/C++ 程序开发。否(使用 MSVC 工具链时必选)
Ninja 高效的构建工具,常与 CMake 配合使用,执行编译和链接,作用类似 Linux 平台的 Make。否
CMake 跨平台构建系统生成工具,用于配置项目并生成构建文件。否(使用 CMake 管理项目时必选)
Qt CreatorQt 集成开发环境,提供代码编辑、项目管理、编译和调试等功能。否(使用 Qt Creator 开发时必选)
Qt Design Studio 用于可视化设计 QML 界面、创建动画和 UI 原型。否
  • 组件说明:

    • MinGW 和 MSVC 二选一即可,通常不需要同时安装;具体取决于选择的 Qt 编译器套件(如下图所示)。
    • CMake 和 Ninja 并非所有项目都必须使用,Qt 项目也可以采用其他构建工具,例如 QMake(不推荐)。
    • Qt Creator 和 Qt Design Studio 是不同工具:前者负责日常编码与调试,后者侧重 QML 界面设计。
    • 如果是初学 Qt,建议安装 Qt SDK、Qt Creator、Qt Design Studio,以及与所选 Qt 套件匹配的编译器。
  • 注意事项:

    • 如果 Qt 在线安装失败并提示错误信息 server replied: Too Many Requests,可以通过安装参数 --mirror 切换镜像源,然后重新安装。
    • 比如切换使用阿里的 Qt 镜像源:qt-online-installer-windows-x64-4.11.0.exe --mirror https://mirrors.aliyun.com/qt。

QML 基础概念

QML 是一种用于描述用户界面及其交互逻辑的声明式语言,开发者可以通过简洁的语法定义界面元素、属性、布局、动画以及属性之间的绑定关系;Qt Quick 则是 Qt 提供的一套用于构建动态、流畅用户界面的技术框架,包含丰富的 QML 类型和相关功能。二者通常配合使用:QML 负责描述界面,Qt Quick 提供构建界面所需的类型和功能,开发者还可以通过 C++ 扩展 QML 类型或实现复杂业务逻辑,从而结合 QML 的界面开发效率与 C++ 的性能优势。

QML 快速入门

第一个 QML 程序

示例代码

  • 使用任意编辑器(如 VSCode)编写 QML 源文件(如 first.qml)
1
2
3
4
5
6
7
8
9
10
11
12
13
// 导入外部库或者内部代码
import QtQuick

// Text 类型定义
Text {
// 属性赋值
width: 400
height: 300
font.pixelSize: 32
text: "HelloWorld"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}

运行步骤

  • 通过 qml.exe 直接运行 QML 源文件(如 first.qml),要求 Qt 及相关组件已安装在本地操作系统
  • 比如:D:/dev/qt/6.5.2/msvc2019_64/bin/qml.exe first.qml

运行效果

Login UI 应用程序

示例代码

  • 使用任意编辑器(如 VSCode)编写 QML 源文件(如 login.qml)
1
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
import QtQuick
import QtQuick.Controls
import QtQuick.Controls.Basic

// 主窗口
ApplicationWindow {
id: root
width: 1280
height: 800
visible: true // 默认显示窗口
title: "Login UI"
color: "#00000000"
flags: Qt.FramelessWindowHint // 隐藏窗口的标题栏
property int dragX: 0
property int dragY: 0
property bool dragging: false // 是否正在拖动(自定义窗口拖动状态属性)
// 主窗口背景矩形
Rectangle {
width: parent.width
height: parent.height
radius: 10
// 鼠标区域,用于拖动无边框窗口
MouseArea {
width: parent.width
height: 100
onPressed: {
root.dragX = mouseX;
root.dragY = mouseY;
root.dragging = true;
}
onReleased: {
root.dragging = false;
}
onPositionChanged: {
if (root.dragging) {
root.x += mouseX - root.dragX;
root.y += mouseY - root.dragY;
root.dragX = mouseX;
root.dragY = mouseY;
}
}
}
// 背景渐变色
gradient: Gradient {
GradientStop {
position: 0
color: "#4158d0"
}
GradientStop {
position: 1
color: "#c850c0"
}
orientation: Gradient.Horizontal // 设置背景水平渐变色
}
// 登录面板矩形
Rectangle {
width: 800
height: 500
radius: 10 // 圆角效果
anchors.centerIn: parent // 居中显示
// 图片
Image {
id: image
x: 57
y: 100
source: "images/q2.png"
// 定义图片旋转状态,并通过 Transition 实现状态切换动画
states: [
State {
name: "rotated"
PropertyChanges {
target: image
rotation: 180
}
}
]
transitions: Transition {
RotationAnimation {
duration: 1000 // 动画持续时间(毫秒)
direction: RotationAnimation.Counterclockwise
}
}
MouseArea {
anchors.fill: parent
onClicked: {
if (image.state == "rotated") {
image.state = "";
} else {
image.state = "rotated";
}
}
}
}
// 标题
Text {
x: 530
y: 130
width: 120
height: 30
font.pixelSize: 24
text: qsTr("登录系统")
color: "#333333"
}
// 用户名
TextField {
id: username
x: 440
y: 200
width: 300
height: 50
font.pixelSize: 20
leftPadding: 60
color: "#666666" // 输入文本颜色
placeholderText: qsTr("用户名或邮箱") // 占位提示文本
placeholderTextColor: "#999999" // 占位提示文本颜色
background: Rectangle {
color: "#e6e6e6"
border.color: "#e6e6e6"
radius: 25
}
// 图标
Image {
x: 30
y: 15
width: 20
height: 20
source: username.activeFocus ? "images/u2.png" : "images/u1.png"
}
// 输入框入场动画,使其沿 Y 轴移动
NumberAnimation on y {
from: username.y - 50
to: username.y
duration: 300 // 动画持续时间(毫秒)
}
}
// 密码
TextField {
id: password
x: username.x
y: username.y + username.height + 10
width: username.width
height: username.height
font.pixelSize: username.font.pixelSize
leftPadding: username.leftPadding
color: username.color // 输入文本颜色
placeholderText: qsTr("密码") // 占位提示文本
placeholderTextColor: username.placeholderTextColor // 占位提示文本颜色
echoMode: TextInput.Password
background: Rectangle {
color: username.background.color
border.color: username.background.color
radius: username.background.radius
}
// 图标
Image {
x: 30
y: 15
width: 20
height: 20
source: password.activeFocus ? "images/p2.png" : "images/p1.png"
}
}
// 登录按钮
Button {
id: submit
x: username.x
y: password.y + password.height + 10
width: username.width
height: username.height
font.pixelSize: 20
text: qsTr("登 录")
background: Rectangle {
radius: 25
color: {
if (submit.down) {
return "#00b846";
}
if (submit.hovered) {
return "#333333";
}
return "#57b846";
}
}
// 处理登录按钮点击事件
onClicked: {
print("登录," + username.text + " : " + password.text);
}
}
}
}
// 关闭窗口的按钮
Rectangle {
x: root.width - 35
y: 5
width: 30
height: 30
color: "#00000000"
Text {
text: "×"
font.pixelSize: 28
anchors.centerIn: parent
}
// 鼠标区域,用于处理关闭按钮的交互
MouseArea {
anchors.fill: parent
onEntered: parent.color = "#1BFFFFFF"
onExited: parent.color = "#00000000"
onPressed: parent.color = "#3BFFFFFF"
onReleased: parent.color = "#1BFFFFFF"
// 点击事件
onClicked: {
root.close();
}
}
}
}

下载完整的案例代码

  • 本节完整的 Login UI 案例代码(包括图片资源文件)可以从 GitHub 获取得到。

运行步骤

  • 通过 qml.exe 直接运行 QML 源文件(如 login.qml),要求 Qt 及相关组件已安装在本地操作系统
  • 比如:D:/dev/qt/6.5.2/msvc2019_64/bin/qml.exe login.qml

运行效果