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 类:

  • 内置属性:组件自带的属性(如 widthheightcolortext)。
  • 自定义属性:用 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 有两套核心布局方式,结合使用可实现任意复杂的自适应界面:

  1. 锚定布局(Anchors):通过 “锚点对齐” 定位组件(如 anchors.centerIn: parentanchors.left: btn.right),适合精准定位。
  2. 弹性布局(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)
        }
    }
}

总结

  1. QML 是声明式界面语言,核心是组件化、属性、信号槽,语法简洁易上手;
  2. 布局核心是锚定(精准定位)+ 弹性布局(自适应),两者结合可实现所有界面需求;
  3. QML 负责界面交互,C++ 负责底层逻辑,是 Qt 开发的经典搭配;
  4. 关键优势是跨平台、高性能,适合开发移动端 / 桌面端 / 嵌入式界面。
Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐