QML 全面详解(从核心概念到实战用法)
QML是Qt框架中的声明式UI编程语言,专为快速开发跨平台界面设计。核心特点包括:组件化结构、简洁语法(类似HTML+JS)、动态属性绑定和信号槽交互机制。支持锚定与弹性两种布局方式,可高效实现复杂自适应界面。QML与C++深度集成,既能独立开发轻量UI,也可结合C++处理业务逻辑。其跨平台特性(Windows/macOS/Linux/Android/iOS)和底层C++渲染引擎,使其成为移动端、
QML(Qt Modeling Language)是 Qt 框架中用于快速开发跨平台界面的声明式编程语言,核心特点是 “所见即所得”,结合了声明式语法和 JavaScript 逻辑,专门为图形界面(GUI)设计,既能写简单的按钮、文本,也能开发复杂的移动端 / 桌面端应用。
一、QML 核心定位
- 本质:声明式语言(描述 “界面长什么样”,而非 “怎么画出来”),对比传统的命令式语言(如 C++ 一步步写绘制逻辑),QML 更简洁、直观。
- 核心优势:跨平台(Windows/macOS/Linux/Android/iOS)、高性能(底层由 Qt C++ 实现渲染)、易上手(语法接近 HTML+JS)、支持动态交互。
- 应用场景:Qt Quick 应用(移动端 / 桌面端界面)、嵌入式设备 UI、车载系统界面、多媒体应用等。
二、QML 基础语法
1. 基本结构(组件化)
QML 以组件(Component) 为核心,每个 QML 文件本质是一个可复用的组件,结构分为 3 部分:
qml
// 1. 导入模块(类似JS的import、Python的import)
import QtQuick 2.15 // 核心UI组件(矩形、文本、图片等)
import QtQuick.Controls 2.15 // 标准控件(按钮、输入框、列表等)
// 2. 根组件(每个QML文件必须有且只有一个根组件)
Rectangle { // 矩形组件(内置基础组件)
// 3. 属性(描述组件的特征:宽、高、颜色、位置等)
width: 400 // 宽度
height: 300 // 高度
color: "#f5f5f5" // 背景色(支持十六进制、英文名称)
// 子组件(嵌套在根组件内,实现界面组合)
Text {
text: "Hello QML!" // 显示文本
font.pixelSize: 24 // 字体大小
color: "blue" // 文字颜色
anchors.centerIn: parent // 锚定:在父组件(矩形)正中间
}
Button {
text: "点击我"
anchors.bottom: parent.bottom // 锚定:父组件底部
anchors.horizontalCenter: parent.horizontalCenter // 水平居中
anchors.bottomMargin: 20 // 底部偏移20px
// 交互逻辑(信号槽,类似JS事件)
onClicked: {
console.log("按钮被点击了!") // 控制台输出
parent.color = "lightgreen" // 修改父组件颜色
}
}
}
2. 核心语法规则
表格
| 语法特征 | 说明 | 示例 |
|---|---|---|
| 大小写敏感 | 组件名、属性名区分大小写(如 width 不能写 Width) |
Color: red ❌ / color: red ✅ |
| 属性赋值 | 用 属性名: 值 格式,值可以是数字、字符串、布尔、表达式等 |
width: parent.width / 2(宽度为父组件的一半) |
| 注释 | 单行注释 //,多行注释 /* ... */ |
和 JavaScript 注释规则一致 |
| 表达式 | 属性值支持 JS 表达式、变量、函数调用 | color: isActive ? "red" : "gray"(三元表达式) |
| 信号槽 | 组件的事件(如点击、鼠标移入)通过 on+信号名 绑定逻辑 |
onClicked: { ... }(按钮点击事件) |
三、QML 核心概念
1. 组件(Component)
QML 的最小复用单元,分为两类:
- 内置组件:Qt 自带的基础组件,如
Rectangle(矩形)、Text(文本)、Image(图片)、Button(按钮)、TextField(输入框)等。 - 自定义组件:将一段 QML 保存为
.qml文件(文件名首字母大写),即可作为组件复用,例如:qml
使用自定义组件:// MyButton.qml(自定义按钮组件) import QtQuick 2.15 import QtQuick.Controls 2.15 Button { width: 100 height: 40 font.pixelSize: 16 color: "white" background: Rectangle { color: pressed ? "#2E8B57" : "#3CB371" // 按下/常态颜色 radius: 8 // 圆角 } }qml
import QtQuick 2.15 Rectangle { width: 300 height: 200 MyButton { // 直接使用自定义组件 text: "自定义按钮" anchors.centerIn: parent } }
2. 属性(Property)
描述组件特征的关键,分为 3 类:
- 内置属性:组件自带的属性(如
width、height、color、text)。 - 自定义属性:用
property 类型 名称: 默认值定义,例如:qml
Rectangle { property int count: 0 // 自定义整数属性 property string userName: "张三" // 自定义字符串属性 property bool isOnline: true // 自定义布尔属性 Text { text: "用户名:" + userName + ",状态:" + (isOnline ? "在线" : "离线") } } - 附加属性:由其他模块提供的属性(如布局的
Layout.fillWidth、锚定的anchors.left)。
3. 信号与槽(Signals & Slots)
QML 实现交互的核心,信号是组件发出的事件(如按钮点击 clicked、文本框输入 textChanged),槽是处理信号的逻辑(JS 代码)。
- 基础用法:
on+信号名: { 逻辑代码 } - 常用信号示例:
qml
TextField { placeholderText: "输入内容..." // 文本变化时触发 onTextChanged: { console.log("当前输入:", text) } // 按下回车时触发 onAccepted: { console.log("回车确认:", text) } } MouseArea { // 鼠标交互区域 anchors.fill: parent // 鼠标按下时触发 onPressed: { console.log("鼠标按下,位置:", mouseX, mouseY) } // 鼠标双击时触发 onDoubleClicked: { parent.color = "yellow" } }
4. 动态绑定(Binding)
QML 支持属性的双向动态绑定,当绑定的源属性变化时,目标属性自动更新:
qml
Rectangle {
width: 400
height: 300
property int num: 0
Text {
// 动态绑定:text 跟随 num 变化
text: "当前数值:" + num
font.pixelSize: 20
anchors.top: parent.top
anchors.topMargin: 20
anchors.horizontalCenter: parent.horizontalCenter
}
Button {
text: "数值+1"
anchors.bottom: parent.bottom
anchors.bottomMargin: 20
anchors.horizontalCenter: parent.horizontalCenter
onClicked: {
num += 1 // 点击后num变化,Text的text会自动更新
}
}
}
四、QML 布局体系
QML 有两套核心布局方式,结合使用可实现任意复杂的自适应界面:
- 锚定布局(Anchors):通过 “锚点对齐” 定位组件(如
anchors.centerIn: parent、anchors.left: btn.right),适合精准定位。 - 弹性布局(Layouts):基于
RowLayout/ColumnLayout/GridLayout,支持比例分配、尺寸约束,适合自适应布局(如按钮等分布局)。
五、QML 与 C++ 交互(进阶)
QML 负责界面展示,C++ 负责底层逻辑(如数据处理、网络请求),两者可双向交互:
- C++ 暴露对象 / 方法给 QML 调用;
- QML 调用 C++ 方法、访问 C++ 属性;
- C++ 触发信号,QML 响应;QML 触发信号,C++ 响应。
示例(C++ 暴露对象给 QML):
cpp
运行
// C++ 代码
#include <QObject>
#include <QQmlContext>
class MyBackend : public QObject {
Q_OBJECT
Q_PROPERTY(QString msg READ msg WRITE setMsg NOTIFY msgChanged)
public:
QString msg() const { return m_msg; }
void setMsg(const QString& msg) {
m_msg = msg;
emit msgChanged();
}
signals:
void msgChanged();
void sendToQml(QString data);
public slots:
QString getHello() { return "Hello from C++!"; }
private:
QString m_msg;
};
// 主函数
int main(int argc, char *argv[]) {
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
MyBackend backend;
engine.rootContext()->setContextProperty("backend", &backend); // 暴露给QML
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
QML 调用 C++:
qml
// QML 代码
import QtQuick 2.15
import QtQuick.Controls 2.15
Rectangle {
width: 400
height: 300
Text {
text: backend.msg // 访问C++属性
font.pixelSize: 20
anchors.top: parent.top
anchors.topMargin: 20
}
Button {
text: "调用C++方法"
anchors.bottom: parent.bottom
anchors.bottomMargin: 20
onClicked: {
let res = backend.getHello() // 调用C++方法
console.log(res) // 输出 "Hello from C++!"
backend.msg = "QML 修改了C++属性" // 修改C++属性
}
}
// 响应C++信号
Connections {
target: backend
function onSendToQml(data) {
console.log("C++ 发送数据:", data)
}
}
}
总结
- QML 是声明式界面语言,核心是组件化、属性、信号槽,语法简洁易上手;
- 布局核心是锚定(精准定位)+ 弹性布局(自适应),两者结合可实现所有界面需求;
- QML 负责界面交互,C++ 负责底层逻辑,是 Qt 开发的经典搭配;
- 关键优势是跨平台、高性能,适合开发移动端 / 桌面端 / 嵌入式界面。
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐


所有评论(0)