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