QML和 C++对象能够经过,signals,slots和 属性修改进行交互。对于一个C++对象,任何数据均可以经过Qt的 Meta-Object System暴露给QML(何总方法,后面介绍),同时,任何的QML对象数据经过Meta-object system在C++端直接访问。
在实际的项目中不少地方会用到QML与Qt C++交互。在这里总结了若干方法供你们参考,欢迎你们指导和拍砖。
html
在这里不外乎有三种方法:
1. 把Qt C++中的对象或类型暴露给 QML端,供QML端使用。(官方说法是“嵌入”而非“暴露”,比较文明。- -b)
2. QML中的Signal Handler(至关于Qt C++发送信号给QML端,QML端的Signal Handler进行处理)。
3. 在Qt C++端建立QML对象,既然对象都有了。那你想怎么样它就怎么样它呗。(没用过,看起来也不太实用,不过介绍介绍,有用过的同窗留言哈)。
函数
好,咱们开始吧~ui
别急,让咱们先来看看,一些东西,若是您都知道,能够跳过此节。
QML API有三个主要成员——QDeclarativeEngine,QDeclarativeComponent和QDeclarativeContext。
spa
QDeclarativeEngine提供了QML的运行环境。
QDeclarativeComponent封装了QML Documents。
QDeclarativeContext容许程序使用QML组件显示数据。
code
QML包含一个很是好用的API——QDeclarativeView。经过它,应用程序能够很方便的把QML组件嵌入到QGraphicsView中。QDeclarativeView主要用于在应用程序开发过程当中进行快速原型开发。component
#ifndef MYCLASS_H #define MYCLASS_H #include <QObject> #include <QString> class MyClass : public QObject { Q_OBJECT Q_PROPERTY(QString myString READ myString WRITE setmyString NOTIFY myStringChanged) public: explicit MyClass(QObject *parent = 0); Q_INVOKABLE QString getMyString(); signals: void myStringChanged(); public slots: void setmyString(QString aString); QString myString(); private: QString m_string; }; #endif // MYCLASS_H
若你想数据元素中的方法能够被QML直接调用有2种方法:
1. 在函数申明前添加 Q_INVOKABLE 宏。
2. 申明成public slots。
htm
QML能够直接访问改数据元素的属性,该属性由QPROPERTY所申明。
具体实现请参考,示例代码。
对象
//main.cpp MyClass myObj; QDeclarativeEngine *engine=viewer.engine(); QDeclarativeContext *context=engine->rootContext(); context->setContextProperty("myObjectExposeByCXProperty", &myObj);
qml中能够直接使用myObjectExposeByCxProperty对象。ci
//mainpage.qml ... Button{ ... id:btn1 ... text: qsTr("PROPERTY") //此处调用myString为MyClass的QPROPERTY的属性不是方法,因此没有括号。 onClicked: label.text=myObjectExposeByCXProperty.myString; } ...
另一种方式是注册类型开发
//main.cpp qmlRegisterType<MyClass>("RegisterMyType", 1, 0, "MyClassType");
QML中这样使用
//mainpage.qml ... import RegisterMyType 1.0 Button{ id:btn2 ... text: qsTr("INOVKABLE") //此处调用的时INVOKABLE的方法,不是属性,因此有括号。 onClicked: label.text=myclassExposeByRegType.getMyString(); } //建立对象,因为QML是解释执行的,因此放后面也没什么关系。 MyClassType { id:myclassExposeByRegType }
步骤:
1. 导入import。
2. 建立对象。
3. id直接使用。
仍是使用上面的那例子,在qml中点击按钮控件,改变其中对象的字符串,这时候在Qt C++中发送一个signal信号给qml端,qml端接收到使用signal handler响应,改变label2的值。具体代码以下。
qml中修改string的值。
//mainpage.qml Button{ id:btn3 text: qsTr("emit stringchanged signal") onClicked: myObjectExposeByCXProperty.myString="xxxxx"; }
Qt C++触发信号
//myclass.cpp void MyClass::setmyString(QString aString) { if(aString==m_string) { return; } m_string=aString; emit myStringChanged(); }
链接signal handler响应
//mainpage.qml Connections { target: myObjectExposeByCXProperty onMyStringChanged:label2.text="Signal handler received" }
一样的QML的函数也能够被Qt C++端调用。
全部的QML函数都经过meta-object system暴露Qt C++端,在Qt C++端可使用QMetaObject::invokeMethod()方法直接调用。下面就是这样的一个例子。
// MyItem.qml import QtQuick 1.0 Item { function myQmlFunction(msg) { console.log("Got message:", msg) return "some return value" } }
// main.cpp QDeclarativeEngine engine; QDeclarativeComponent 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;
注意:QMetaObject::invokeMethod()方法中的参数Q_RETURN_ARG()和Q_ARG()都被定义为QVariant类型,此类型是QML函数的的参数和返回值的通用数据类型。
转自:http://www.developer.nokia.com/Community/Wiki/QML%E4%B8%8EQt_C%2B%2B_%E4%BA%A4%E4%BA%92%E6%9C%BA%E5%88%B6%E6%8E%A2%E8%AE%A8%E4%B8%8E%E6%80%BB%E7%BB%93