qml c++混合编程注意事项

在Qml和C++类进行数据交互时,通用的办法都是注册C++到Qml中,但是很多时候C++的对象是在C++中进行创建,如果在Qml中创建了,数据之间的交互就会出现无法控制的问题。
信号与槽、上下文等都是数据交互的方式,但是当嵌套多层时,内部的C++对象和内部的Qml内容交互无法直接连接。此时就需要通过一个代理的C++类作为数据和消息的连接通道。

利用一个中间的代理类实现嵌套的消息和数据的交互,注册为engine的上下文
例子:

class HiddenClass {
public:
    int getData() const { return 42; }
};

// 中间代理类
class ProxyClass : public QObject {
    Q_OBJECT
    Q_PROPERTY(int data READ data NOTIFY dataChanged)
public:
    explicit ProxyClass(QObject *parent = nullptr) :QObject(parent), m_hiddenClass() 
    {}
    int data() const { return m_hiddenClass.getData(); }
signals:
    void dataChanged();
private:
    HiddenClass m_hiddenClass;
};

// main.qml
import QtQuick
import QtQuick.Window

Window {
    width: 640
    height: 480
    visible: true
    title: "Indirect C++ Access"

    Text {
        id: textItem
        anchors.centerIn: parent
        text: "Data from hidden class: " + proxy.data
    }
}

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

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

    ProxyClass proxy;
    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("proxy", &proxy);

    const QUrl url(u"qrc:/main.qml"_qs);
    engine.load(url);

    return app.exec();
}

嵌套的交互,通知类、触发类的动作可以通过嵌套的信号与槽和C++绑定

#include <QObject>
class MyClass : public QObject {
    Q_OBJECT
public:
    explicit MyClass(QObject *parent = nullptr) : QObject(parent) {}
signals:
    void dataChanged(const QString &newData);
public slots:
    void updateData(const QString &data) {
        emit dataChanged(data);
    }
};

// main.qml
import QtQuick
import QtQuick.Window

Window {
    width: 640
    height: 480
    visible: true
    title: "Nested QML Interaction"
    // 嵌套的QML组件
    MyNestedComponent {
        id: nestedComponent
    }
    Component.onCompleted: {
        myObject.dataChanged.connect(nestedComponent.onDataChanged);
    }
    Button {
        id: updateButton
        anchors.bottom: parent.bottom
        anchors.horizontalCenter: parent.horizontalCenter
        text: "Update Data"
        onClicked: {
            myObject.updateData("New data from QML");
        }
    }
}
// MyNestedComponent.qml
import QtQuick
Item {
    width: 200
    height: 100
    Text {
        id: textItem
        anchors.centerIn: parent
        text: "Initial data"
    }
    signal dataChangedFromC++(string newData)
    function onDataChanged(newData) {
        textItem.text = newData;
    }
}

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "myclass.h"
int main(int argc, char *argv[]) {
    QGuiApplication app(argc, argv);
    MyClass myObject;
    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("myObject", &myObject);
    const QUrl url(u"qrc:/main.qml"_qs);
    engine.load(url);
    return app.exec();
}

使用 findChild 方法查找嵌套对象,通过将QQmlEngine对象全局化,实现通过engint的root找到嵌套的对象,

// main.qml
import QtQuick
import QtQuick.Window
Window {
    width: 640
    height: 480
    visible: true
    title: "Find Nested QML Object"
    Item {
        id: nestedItem
        objectName: "nestedItem"
        function doSomething() {
            console.log("Doing something in nested item");
        }
    }
}

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

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

    QQmlApplicationEngine engine;
    const QUrl url(u"qrc:/main.qml"_qs);
    engine.load(url);

    QObject *root = engine.rootObjects().first();
    if (root) {
        // 查找嵌套的QML对象
        QObject *nestedObject = root->findChild<QObject*>("nestedItem");
        if (nestedObject) {
            // 调用嵌套对象的方法
            QMetaObject::invokeMethod(nestedObject, "doSomething");
        }
    }

    return app.exec();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值