ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Qt中C++与Qml互相调用

2022-03-25 13:02:23  阅读:191  来源: 互联网

标签:QVariant Qt MyItem C++ QObject qml Qml QML


QML调用C++

思路

一种解决方案:

使用Qt中的QML调用C++中的类,首先使用需要定义一个继承自 QObject 的类,然后将这个类注册到 QML 中去,然后在这个类使用 Q_INVOKABLE 这个宏修饰的函数,都可以直接在QML中调用。

示例:

## 0x01 定义一个C++类

#include <QObject>
#include <QDebug>

class QmlBrg : public QObject
{
    Q_OBJECT
public:
    explicit QmlBrg(QObject *parent = nullptr);
    Q_INVOKABLE void ssss() const noexcept { qDebug() << "qml确实调我了!"; }

signals:

};


## 0x02 注册到QML中去

    QmlBrg* qbrg = new QmlBrg;
	/** 在QML中这个实例名就叫 cbrg **/
    qmlwid->rootContext()->setContextProperty("cbrg",  qbrg);
	
### 0x03 在QML中调用

onClicked: {
	console.log("我要调用 C++ !")
		cbrg.ssss();
	}

C++调用 QML

https://blog.csdn.net/baidu_33850454/article/details/81941675
1.1通过 objectName 来获取QML对象
假设MyItem.qml的内容如下,Item中存在一个objectName为“rect”的矩形

import QtQuick 2.0

Item {
    width: 100; height: 100

    Rectangle {
        anchors.fill: parent
        objectName: "rect"
    }
}

则 上述 矩形可以通过 如下方式获取:

QObject *rect = object->findChild<QObject*>("rect");
if (rect)
    rect->setProperty("color", "red");
	

如果存在多个objectName相同的对象,比如listView的Delegate中设置了一个特定的对象名称,则可以使用QObject::findChildren()来获取所有子对象。

警告: 尽管可以从C++中获取和操作QML对象,但是除非为了测试和原型设计,并不建议这样做。因为QML和C ++集成的优势之一是能够在QML中实现与C ++逻辑和后端分离的UI。

1.2从C ++访问QML对象类型的成员
在QML中使用property声明的属性可以在C++中被获取。假设MyItem.qml的内容如下:

// MyItem.qml
import QtQuick 2.0

Item {
    property int someNumber: 100
}

则someNumber属性值可以通过QQmlProperty,QObject::setProperty() 和QObject::property()来访问。

QQmlEngine engine;
QQmlComponent component(&engine, "MyItem.qml");
QObject *object = component.create();

qDebug() << "Property value:" << QQmlProperty::read(object, "someNumber").toInt();
QQmlProperty::write(object, "someNumber", 5000);

qDebug() << "Property value:" << object->property("someNumber").toInt();
object->setProperty("someNumber", 100);

注意:你必须通过QObject::setProperty(), QQmlProperty or QMetaProperty::write()这三种方法来设置QML的属性,才能够保证QML引擎对你的修改可知。

2、调用QML函数
所有的QML函数都暴露在Qt元对象系统中,可以被C++使用QMetaObject::invokeMethod()来访问。向QML传递的函数参数和QML的返回值需要在C ++中转换为QVariant值,因为这是QML函数参数和返回值的通用数据类型。例如:

// MyItem.qml
import QtQuick 2.0

Item {
    function myQmlFunction(msg) {
        console.log("Got message:", msg)
        return "some return value"
    }
}

C++ 代码如下:

// main.cpp
QQmlEngine engine;
QQmlComponent component(&engine, "MyItem.qml");
QObject *object = component.create();

QVariant returnedValue;
QVariant msg = "Hello from C++";
QMetaObject::invokeMethod(object, "myQmlFunction",
        Q_RETURN_ARG(QVariant, returnedValue),
        Q_ARG(QVariant, msg));

qDebug() << "QML function returned:" << returnedValue.toString();
delete object;

13
3、连接QML信号
所有的QML信号均可以在C++中被访问,可以像普通Qt的C++信号一样使用。
QML信号参数为string:

// MyItem.qml
import QtQuick 2.0

Item {
    id: item
    width: 100; height: 100

    signal qmlSignal(string msg)

    MouseArea {
        anchors.fill: parent
        onClicked: item.qmlSignal("Hello from QML")
    }
}

C++处理方式如下:

class MyClass : public QObject
{
    Q_OBJECT
public slots:
    void cppSlot(const QString &msg) {
        qDebug() << "Called the C++ slot with message:" << msg;
    }
};

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

    QQuickView view(QUrl::fromLocalFile("MyItem.qml"));
    QObject *item = view.rootObject();

    MyClass myClass;
    QObject::connect(item, SIGNAL(qmlSignal(QString)),
                     &myClass, SLOT(cppSlot(QString)));

    view.show();
    return app.exec();
}

需要注意的是,当信号参数时QML对象时,参数类型应该为var,C++中槽函数的参数应该为QVariant。
QML文件如下:

// MyItem.qml
import QtQuick 2.0

Item {
    id: item
    width: 100; height: 100

    signal qmlSignal(var anObject)

    MouseArea {
        anchors.fill: parent
        onClicked: item.qmlSignal(item)
    }
}

则C++处理方式如下:

class MyClass : public QObject
{
    Q_OBJECT
public slots:
    void cppSlot(const QVariant &v) {
       qDebug() << "Called the C++ slot with value:" << v;

       QQuickItem *item =
           qobject_cast<QQuickItem*>(v.value<QObject*>());
       qDebug() << "Item dimensions:" << item->width()
                << item->height();
    }
};

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

    QQuickView view(QUrl::fromLocalFile("MyItem.qml"));
    QObject *item = view.rootObject();

    MyClass myClass;
    QObject::connect(item, SIGNAL(qmlSignal(QVariant)),
                     &myClass, SLOT(cppSlot(QVariant)));

    view.show();
    return app.exec();
}

参考链接:http://doc.qt.io/qt-5/qtqml-cppintegration-interactqmlfromcpp.html

标签:QVariant,Qt,MyItem,C++,QObject,qml,Qml,QML
来源: https://www.cnblogs.com/mc-r/p/16054140.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有