QML 时常需要从C++的代码中引用类或者方法来达到QML无法执行的内容。由于QML是解释执行的,无法直接引用C++中的类,所以需要用QT的方法进行传递参数。

首先建立一个项目,选择:Qt Quick Application

他会生成这些 main.cpp 代码:

#include <QGuiApplication>
#include <QQmlApplicationEngine>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;  // 初始化Engine对象
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));  // 载入QML文件
    // 判断内容是否错误,如果错误则退出程序
    if (engine.rootObjects().isEmpty()) {
        return -1;
    }
    return app.exec();
}

我们新建一个类,叫做 BackEnd 并定义内容。

#ifndef BACKEND_H
#define BACKEND_H

#include <QObject>
#include <QString>

class BackEnd : public QObject  // 继承自QObject类
{
    Q_OBJECT // 建立QObject
    Q_PROPERTY(QString userName READ userName WRITE setUserName NOTIFY userNameChanged)  // 建立属性内容
public:
    explicit BackEnd(QObject *parent = nullptr);

    QString userName();
    void setUserName(const QString &userName);

signals:
    void userNameChanged();  // 修改后的返回信号

private:
    QString m_userName;
};

#endif // BACKEND_H

BackEnd 类的函数:

#include "backend.h"

BackEnd::BackEnd(QObject *parent) : QObject(parent){}

QString BackEnd::userName()
{
    return m_userName;
}

void BackEnd::setUserName(const QString &userName)
{
    if (userName == m_userName){
        return;
    }
    m_userName = userName;
    emit userNameChanged();
}

然后定义QML文件:

import QtQuick 2.6
import QtQuick.Controls 2.0
import io.qt.examples.backend 1.0

ApplicationWindow {
    id: root
    width: 300
    height: 480
    visible: true

    BackEnd {
        id: backend
    }

    TextField {
        text: backend.userName
        placeholderText: qsTr("User name")
        anchors.centerIn: parent

        onTextChanged: backend.userName = text
    }
}

最后,修改Main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>

#include "backend.h"

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    qmlRegisterType<BackEnd>("io.qt.examples.backend", 1, 0, "BackEnd");

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

使用BackEnd实例可以访问userName属性,该属性在TextField的text属性更改时更新。