qml与c++交互2,多种交互方式

qml可以通过注入,导入模块,上下文等多种方式进行注入,使用场景各不相同

先看main文件,头文件中调用几个FUNC,对应几种交互方式,

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QDebug>
#include "qml_cpp.h"
#include "qmloperation.h"


int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif

    QGuiApplication app(argc, argv);

    QmlOperation *MyFunc = new QmlOperation;

    QQmlApplicationEngine engine;
    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);

    MyFunc->Func3(engine);
    MyFunc->Func2(engine);
    engine.load(url);

    MyFunc->Func1(engine);



    return app.exec();
}


// Second, register the singleton type provider with QML by calling this function in an initialization function.


接着看cpp文件中具体的交互:头文件中几个func调用函数说明交互的方式;

头文件:

#ifndef QMLOPERATION_H
#define QMLOPERATION_H

#include <QObject>
#include <QQmlApplicationEngine>

#include "qml_cpp.h"

class QmlOperation: public QObject
{
    Q_OBJECT
    // qml 交互使用
    Q_PROPERTY (int someProperty READ someProperty WRITE setSomeProperty NOTIFY somePropertyChanged)
public:
    QmlOperation();

    void Func1(QQmlApplicationEngine &engine);     // cpp调用qml中函数, 直接访问Q
    void Func2(QQmlApplicationEngine &engine);     // 注册一个单列模块
    void Func3(QQmlApplicationEngine &engine);     //设置上下文属性,上下文导入,zuiohao
    void Func4(QQmlApplicationEngine &engine);     // 注册一种类型class,struct,

    Q_INVOKABLE int doSomething() { setSomeProperty(1); return index_; }
    // 数据交互函数
    int someProperty() const { return index_; }
    void setSomeProperty(int val) { index_ = val + index_; emit somePropertyChanged(val); }

public slots:
    // 槽函数
    void recvSlot(int);
signals:
    void  somePropertyChanged(int val);

private:
    int index_;
};

static QObject *exampleProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
 {
     Q_UNUSED(engine)
     Q_UNUSED(scriptEngine)

     QmlOperation *example = new QmlOperation();
     return example;
 }

#endif // QMLOPERATION_H

cpp文件:

#include "qmloperation.h"
#include <QQmlContext>
#include <QDebug>

// 信号与槽函数需要的头文件:
#include <QMetaObject>
#include <QAbstractButton>


QmlOperation::QmlOperation()
{
    index_ = 0;
}

void QmlOperation::Func1(QQmlApplicationEngine &engine)
{
    auto root = engine.rootObjects();

    // ------------------------------------------------------------------
   // 调用qml中的函数
    // findChild 是qml中的objectName名
    auto base = root.first()->findChild<QObject *>("label1");
    QVariant ret;
    // 找到的返回值 函数名 函数返回值  传入参数
    QMetaObject::invokeMethod(base, "getText", Q_RETURN_ARG(QVariant, ret), Q_ARG(QVariant, "---------"));
    qDebug() << "返回值为: " << ret.toString();


    QObject *button = root.first()->findChild<QObject *>("bt1");
    if (button == nullptr) {
        qDebug() << " find qml objectName is err";
    } else {
        qDebug() << " find qml objectName is sucessed";
//        QObject::connect(button,SIGNAL(clicked()),this,SLOT(recvSlot()));
        QObject::connect(button,SIGNAL(bt1Signal(int)), this, SLOT(recvSlot(int)));
    }
}

void QmlOperation::Func2(QQmlApplicationEngine &engine)
{
    // 注册一个接口,叫 MyApi_Func2
    qmlRegisterSingletonType<QmlOperation>("Qt.example.qobjectSingleton", 1, 0, "MyApi_Func2", exampleProvider);
}

void QmlOperation::Func3(QQmlApplicationEngine &engine)
{
    // 传入的数据或者类都是全局的,一般不建议使用,但是目前很多代码中都是大量使用

    qml_cpp *data = new qml_cpp;
    QQmlContext * con =  engine.rootContext();
    con->setContextProperty("dataApi", data);

    int maxData = 99;
    con->setContextProperty("myIndex", maxData);
}

void QmlOperation::Func4(QQmlApplicationEngine &engine)
{
    // 注入 qml_cpp 这个类
    qmlRegisterType<qml_cpp>("modelData", 1, 0, "myData");
}

void QmlOperation::recvSlot(int key)
{
    qDebug() << " qml button is clicked return value is: "<< key;
}

一个作为纯数据交换的文件:

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

    Q_INVOKABLE void prinfData() const noexcept;

signals:
    Q_INVOKABLE void cppSend() const;
    Q_INVOKABLE void CppSendString(QString) const;
private:
    QString str_;
    int cppIndex;
signals:

};


//---------------------------------------------------------

qml_cpp::qml_cpp(QObject *parent) : QObject(parent)
{
    str_ = " this is cpp string data";
}

void qml_cpp::prinfData() const noexcept
{
    qDebug() << " this is cpp func ----------------------------------------------------- printfData";

    emit cppSend();
    emit CppSendString("this is cpp signal");
}

最后是qml文件,三个按钮对应不同的交互方式:

import QtQuick 2.0
import QtQuick.Window 2.12
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.3
 import QtQml 2.12

import './test.js' as MyFunc   // 导入js文件, as 别名
import Qt.example.qobjectSingleton 1.0

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



    ColumnLayout{
        anchors.fill: parent
        RowLayout {
//            anchors.horizontalCenter: parent.horizontalCenter
//            Layout.preferredWidth: parent.width
//            Layout.preferredHeight: 130
            Label {
                objectName: "label1"
                text: " 这是cpp调用qml 中的函数"
                function getText(str) {             // cpp调用qml中的函数
                    return text + str
                }
            }
            Button {
                signal bt1Signal(int index)    // 自定义一个信号
                objectName: "bt1"
                text: "Func1"
                onClicked: {
                    bt1Signal(999)
                }
            }

        }
        RowLayout {
            Label {objectName: "label2"; text: " this is label"}
            Button {
                // func 2
                property int someValue: MyApi_Func2.someProperty
                onSomeValueChanged: {
                    console.log("func2 someValue is changeed, value is : ", someValue)
                }
//                Layout.alignment: Qt.AlignCenter
                objectName: "bt2"
                text: "Func2"
                onClicked: {
                    MyApi_Func2.doSomething();        // 调用 cpp中的 doSomething,使value
                }
            }
        }
        RowLayout {
            Label {objectName: "label3"; text: " 这是 qml调用cpp内部函数"}
            Button {
                objectName: "bt3"
                text: "Func3"
                onClicked: {
                    dataApi.prinfData();
//                    console.log("cpp传入全局变量 myIndex: ", myIndex)
                }
                Connections {
                    target: dataApi
                    function onCppSend() {
                        console.log("this is cpp signal, argument is: ");
                    }
                }
            }
        }
    }
}

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值