一、QML 是什么?

QML(Qt Meta-Object Language)是 Qt 框架推出的声明式编程语言,主打 UI 快速开发,通过简洁的语法描述界面结构与交互逻辑,广泛用于桌面端、移动端、嵌入式设备的图形界面开发。其核心优势是:

  • 声明式语法:描述 “界面是什么样”,而非 “如何实现”,开发效率远超传统 imperative 语言;
  • 跨平台兼容:一次编写可运行于 Windows、Linux、macOS、Android、iOS 等系统;
  • 与 C++ 深度集成:UI 层用 QML 实现,业务逻辑用 C++ 封装,兼顾开发效率与性能。

二、QML 核心基础

1. 基本语法结构

QML 文件以.qml为后缀,核心是 “对象 + 属性” 的层级结构,示例如下:

// 最基础的QML文件(MyFirstQml.qml)
import QtQuick 6.5  // 导入QtQuick模块(提供基础UI组件)
import QtQuick.Controls 6.5  // 导入控件模块(提供按钮、输入框等)

// 根对象:Rectangle(矩形容器)
Rectangle {
    id: root  // 对象唯一标识(类似变量名,可跨对象引用)
    width: 400  // 宽度(支持数值、表达式、其他对象属性)
    height: 300  // 高度
    color: "#f0f0f0"  // 背景色(支持16进制、颜色名)

    // 子对象:Text(文本控件)
    Text {
        id: helloText
        text: qsTr("Hello QML!")  // 文本内容(qsTr支持国际化)
        font.pixelSize: 24  // 字体大小
        color: "#333333"
        // 锚定布局:居中于根对象
        anchors.centerIn: root
    }

    // 子对象:Button(按钮控件)
    Button {
        text: "Click Me"
        anchors.bottom: helloText.top
        anchors.bottomMargin: 20  // 与上方文本的间距
        anchors.horizontalCenter: helloText.horizontalCenter
        // 交互逻辑:点击按钮修改文本
        onClicked: {
            helloText.text = qsTr("Clicked!");
            root.color = "#e0f7fa";  // 修改根对象背景色
        }
    }
}

2. 核心概念解析

概念 说明
导入(import) 必须放在文件开头,导入所需模块(如 QtQuick 提供基础组件,QtQuick.Controls 提供标准控件),格式为import 模块名 版本号
对象(Object) QML 界面由嵌套的对象组成,每个对象对应一个 UI 元素(如 Rectangle、Text、Button),通过{}定义属性。
id 属性 每个对象的唯一标识,用于在其他对象中引用它(如通过root.width获取根对象宽度),不可重复
属性(Property) 对象的特征(如 width、color),支持三种赋值方式:
1. 直接赋值(width: 400);
2. 绑定表达式(height: width * 0.75,自动联动更新);
3. 引用其他对象属性(anchors.centerIn: root)。
锚定布局(Anchors) QML 核心布局方式,通过anchors属性将对象 “锚定” 到其他对象的边缘 / 中心(如anchors.top: parent.topanchors.centerIn: parent),配合margin控制间距。
信号与槽(Signal & Slot) 处理交互逻辑的核心:控件触发 “信号”(如 Button 的clicked),通过on信号名定义 “槽函数”(如onClicked: { ... })。

三、常用布局方式

QML 布局主要解决控件的位置排列问题,核心有 3 种:

1. 锚定布局(Anchors)

最灵活的布局方式,适合不规则排列,示例:

Rectangle {
    width: 300; height: 200; color: "#f5f5f5"
    Text { id: t1; text: "Top Left"; anchors.topLeft: parent.topLeft; anchors.margins: 10 }
    Text { id: t2; text: "Bottom Right"; anchors.bottomRight: parent.bottomRight; anchors.margins: 10 }
    Text { id: t3; text: "Center"; anchors.centerIn: parent }
}

2. 行布局(Row)与列布局(Column)

适合线性排列的控件,自动管理间距,示例:

import QtQuick.Layouts 6.5  // 必须导入布局模块

Column {
    width: 300; anchors.centerIn: parent; spacing: 15  // 控件间距15px
    Button { text: "Button 1"; width: 200 }
    Button { text: "Button 2"; width: 200 }
    Button { text: "Button 3"; width: 200 }
}

3. 网格布局(Grid)

适合多行多列的表格状布局,示例:

Grid {
    width: 300; anchors.centerIn: parent; rows: 2; columns: 2; spacing: 10
    Button { text: "1"; width: 100 }
    Button { text: "2"; width: 100 }
    Button { text: "3"; width: 100 }
    Button { text: "4"; width: 100 }
}

四、数据绑定与动态更新

QML 的 “数据绑定” 是核心特性,当依赖的属性变化时,绑定的属性会自动更新,无需手动赋值:

Rectangle {
    id: root; width: 400; height: 300

    // 滑动条:范围0~255
    Slider {
        id: redSlider; from: 0; to: 255; value: 128
        anchors.top: parent.top; anchors.margins: 20; width: 300
    }

    // 矩形背景色绑定滑动条值
    Rectangle {
        width: 200; height: 200; anchors.centerIn: root
        // 绑定表达式:根据滑动条值动态生成颜色
        color: Qt.rgba(redSlider.value/255, 0.5, 0.5, 1)
    }

    // 文本显示当前颜色值
    Text {
        text: "R: " + Math.round(redSlider.value)
        anchors.bottom: parent.bottom; anchors.margins: 20
    }
}

五、常用控件速查

控件 用途 核心属性 / 信号
Text 显示文本 text(内容)、font(字体)、color(颜色)
Button 触发点击操作 text(按钮文本)、onClicked(点击信号)
TextField 单行文本输入 text(输入内容)、placeholderText(提示文本)、onEditingFinished(输入完成信号)
Slider 数值调节滑块 from(最小值)、to(最大值)、value(当前值)
Image 显示图片 source(图片路径)、fillMode(填充方式)
Rectangle 矩形容器 / 背景 widthheightcolorradius(圆角)

六、实战:简易登录界面

整合上述知识,实现一个包含输入框、按钮、动态提示的登录界面:

import QtQuick 6.5
import QtQuick.Controls 6.5
import QtQuick.Layouts 6.5

Rectangle {
    id: loginWindow; width: 400; height: 300; color: "#f8f9fa"
    title: qsTr("Login"); visible: true

    Column {
        id: loginLayout; anchors.centerIn: parent; spacing: 20; width: 300

        // 标题
        Text {
            text: qsTr("用户登录"); font.pixelSize: 28; color: "#212529"
            anchors.horizontalCenter: parent.horizontalCenter
        }

        // 用户名输入
        TextField {
            id: username; placeholderText: qsTr("请输入用户名"); width: parent.width
            font.pixelSize: 16; padding: 12
            border.color: "#ced4da"; border.width: 1; radius: 4
        }

        // 密码输入
        TextField {
            id: password; placeholderText: qsTr("请输入密码"); width: parent.width
            font.pixelSize: 16; padding: 12; echoMode: TextField.Password
            border.color: "#ced4da"; border.width: 1; radius: 4
        }

        // 错误提示(默认隐藏)
        Text {
            id: errorTip; text: qsTr("用户名或密码不能为空"); color: "red"; visible: false
        }

        // 登录按钮
        Button {
            text: qsTr("登录"); width: parent.width; height: 44; font.pixelSize: 16
            background: Rectangle { color: "#007bff"; radius: 4 }
            onClicked: {
                if (username.text === "" || password.text === "") {
                    errorTip.visible = true;  // 显示错误提示
                } else {
                    errorTip.visible = false;
                    loginWindow.title = qsTr("登录中...");
                    // 此处可添加调用C++登录逻辑的代码
                }
            }
        }
    }
}

七、QML 与 C++ 交互(核心思路)

QML 负责 UI,C++ 负责业务逻辑,交互方式主要有两种:

  1. C++ 对象暴露给 QML
    通过qmlRegisterType注册 C++ 类,QML 中直接创建对象并调用方法;
  2. QML 信号触发 C++ 槽
    QML 中定义信号,C++ 对象连接该信号,触发 C++ 逻辑。

示例(C++ 类注册):

// C++代码:定义LoginManager类
#include <QObject>
class LoginManager : public QObject {
    Q_OBJECT
public slots:
    bool login(const QString &username, const QString &password) {
        return username == "admin" && password == "123456";
    }
};

// 注册到QML引擎
#include <QQmlApplicationEngine>
int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    qmlRegisterType<LoginManager>("com.example", 1, 0, "LoginManager");  // 注册类
    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/Login.qml")));
    return app.exec();
}
// QML中使用C++对象
import com.example 1.0  // 导入注册的模块

LoginManager { id: loginMgr }  // 创建C++对象

// 登录按钮点击逻辑修改
onClicked: {
    if (username.text === "" || password.text === "") {
        errorTip.visible = true;
    } else {
        let result = loginMgr.login(username.text, password.text);  // 调用C++方法
        if (result) {
            loginWindow.title = qsTr("登录成功");
        } else {
            errorTip.text = qsTr("用户名或密码错误");
            errorTip.visible = true;
        }
    }
}

八、快速上手工具

  1. Qt Creator:官方 IDE,内置 QML 编辑器、预览器、调试器,支持实时预览 UI 效果;
  2. QML Preview:Qt Creator 的 “Design” 模式,可拖拽控件生成 QML 代码,适合新手;
  3. Qt Documentation:官方文档(链接),查询控件属性、信号的权威来源。
  4. Visual Studio:集成qml环境,调试高效。(可见下篇文章)

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐