Cpp和Qml进行交互

107 阅读2分钟

创建 Calculator 工具类, 实现加法和减法逻辑, 提供给 qml调用

  • calculator.h
#ifndef CPPACCESSQML_CALCULATOR_H
#define CPPACCESSQML_CALCULATOR_H

#include <QObject>
#include <QDebug>

class Calculator : public QObject {
Q_OBJECT

public:
    explicit Calculator(QObject *parent = nullptr);
    ~Calculator() override;


public slots:
    void plus(int a, int b);

signals:
    void plusResult(int res);
};

#endif //CPPACCESSQML_CALCULATOR_H
  • calculator.cpp
#include "calculator.h"

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

Calculator::~Calculator() {}

void Calculator::plus(int a, int b) {
    qDebug() << "invoke plus, a = " << a << ", b = " << b;
    emit plusResult(a + b);
}

设置QML上下文属性

涉及到信号和槽函数

//main.cpp
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "calculator.h"

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    QQmlApplicationEngine engine;
    //创建Calculator对象
    Calculator calculator;
    //将Calculator对象作为QML上下文属性
    engine.rootContext()->setContextProperty("calculator", &calculator);
    engine.load(QUrl(QStringLiteral("../main.qml")));
    return QApplication::exec();
}

qml 中使用 calculator 对象

import QtQuick
import QtQuick.Controls

Window {
    visible: true
    width: 640
    height: 480
    title: "Hello World"

    Connections {
        target: calculator
        function onPlusResult(res) {
            console.log('plus result = ' + res)
        }
    }

    Rectangle {
        width: 100
        height: 50
        color: 'green'
        Text {
            anchors.centerIn: parent
            text: 'Plus(3 + 5)'
        }
        MouseArea {
            anchors.fill: parent
            onClicked: calculator.plus(3, 5)
        }
    }
}

运行截图

1.png

使用QML类型注册

将 C++ 对象注册为自定义的 QML 类型

修改 calculator.h 文件

Q_PROPERTY 暴露属性, Q_INVOKABLE 暴露方法, 在 qml 中直接能进行访问.

#ifndef CPPACCESSQML_CALCULATOR_H
#define CPPACCESSQML_CALCULATOR_H

#include <QObject>
#include <QDebug>

class Calculator : public QObject {
Q_OBJECT
Q_PROPERTY(QString name READ getName WRITE setName NOTIFY nameChanged)

public:
    explicit Calculator(QObject *parent = nullptr);
    ~Calculator() override;

    QString getName() const { return m_name; }
    void setName(const QString &name) { m_name = name; emit nameChanged(m_name); }
    Q_INVOKABLE void printName() { qDebug() << "name:" << m_name; }

private:
    QString m_name;

public slots:
    void plus(int a, int b);

signals:
    void plusResult(int res);
    void nameChanged(const QString &newName);
};

#endif //CPPACCESSQML_CALCULATOR_H

修改 main.cpp 文件

#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "calculator.h"

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    QQmlApplicationEngine engine;
    qmlRegisterType<Calculator>("com.util", 1, 0, "Calculator");
    engine.load(QUrl(QStringLiteral("../main.qml")));
    return QApplication::exec();
}

qml 中使用 Calculator 类型的对象

import QtQuick
import QtQuick.Controls
import com.util 1.0 //main.cpp中进行注册

Window {
    visible: true
    width: 640
    height: 480
    title: "Hello World"

    Calculator {
        id: calculator
        name: 'AAA'
        onPlusResult: (res) => console.log('plus result = ' + res)
        onNameChanged: (newName) => console.log('name changed -> ' + newName)
    }

    Column {
        Rectangle {
            width: 140
            height: 50
            color: 'green'
            Text {
                anchors.centerIn: parent
                text: calculator.name + ' execute Plus '
            }
            MouseArea {
                anchors.fill: parent
                onClicked: calculator.plus(3, 5)
            }
        }

        Rectangle {
            width: 140
            height: 50
            color: 'yellow'
            Text {
                anchors.centerIn: parent
                text: 'change name'
            }
            MouseArea {
                anchors.fill: parent
                onClicked: calculator.name = "BBB"
            }
        }

        Rectangle {
            width: 140
            height: 50
            color: 'red'
            Text {
                anchors.centerIn: parent
                text: 'print name'
            }
            MouseArea {
                anchors.fill: parent
                onClicked: calculator.printName()
            }
        }
    }
}

运行截图

1.png