1.0 概述

QML 是一种声明式脚本语言 (Qt Meta Language) 作为与 C++ 并列的 Qt 开发语言。

示例:一个具有按钮的页面

import QtQuick 2.14
import QtQuick.Window 2.14
import QtQuick.Controls 2.5

Window {
    id: window
    visible: true
    width: 640
    height: 480
    title: qsTr("Button_Demo")

    Button{
        id: getBtn
        text: "Button"
        width: 120
        height: 40
        onClicked: {
            // TODO 点击回调
        }
    }

}

2.0 QML 与 C++

QML 与 C++ 的交互可以分为四种形式:

  • 注册 C++ 对象到 QML ,在 QML 中访问对象
  • 将 QML 暴露给 C++ 进行操作
  • C++ 创建 QML 对象并进行操作
  • C++ 对象与 QML 通过信号与槽进行交互

本文章进对第一种方式进行介绍 (后续会完善别的方法并在上面进行引用)

3.0 注册 C++ 对象到 QML 并使用

首先创建一个类给 QML 调用:

#include <QObject>

class qmlClass : public QObject
{
    Q_OBJECT
public:
    explicit qmlClass(QObject *parent = nullptr);

    Q_INVOKABLE void setValue(int value);
    Q_INVOKABLE int getValue(void);

signals:

private:
    int Value;
};

创建一个类继承自 QObject 这里简单实现一个获取和设置 value 的方法。

这里需要注意的是两个方法均用 Q_INVOKABLE 关键字进行修饰,这是类中的子方法能被 qml 访问的关键点,不能忽略。

实现前者声明好的方法:

qmlClass::qmlClass(QObject *parent) : QObject(parent){
    this->Value = 100;
}


int qmlClass::getValue(){
    return this->Value;
}

void qmlClass::setValue(int value){
    this->Value = value;
}

现在来到 main.cpp 文件中,使用 qml 引擎将前者编写的类放在其中声明:

qmlClass qclass;
engine.rootContext()->setContextProperty("qmlclass", &qclass);

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>

#include "qmlclass.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    qmlClass qclass;
    engine.rootContext()->setContextProperty("qmlclass", &qclass);


    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}

现在就可以在 qml 中调用前面编写好的代码了:

声明一个 label 用于显示 value

Label{
    id: label
    x: 298
    y: 118
    text: "Value: "
    anchors.horizontalCenter: parent.horizontalCenter
    anchors.bottom: getBtn.top
    anchors.bottomMargin: 5
    anchors.topMargin: 10
}

在按钮的 onClicked 方法中调用我们编写的方法来更新 label 中的文本:

    Button{
        id: getBtn
        text: "getValue"
        anchors.verticalCenterOffset: 0
        anchors.horizontalCenterOffset: 0
        width: 120
        height: 40
        anchors.centerIn: parent

        onClicked: {
            label.text = "Value " + qmlclass.getValue()
        }
    }

实现效果: