C++與QML交互2:在QML中調用C++特性

版權聲明:本文爲博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接和本聲明。
本文連接:https://blog.csdn.net/xi_gua_gua/article/details/56991367
QML引擎(QQmlEngine)集成了Qt元對象系統,由QObject派生的全部子類的屬性、方法和信號等均可以在QML中訪問。QObject是子類有多種辦法將功能暴露給QML訪問:
一、把C++類註冊爲一個可實例化的QML對象類型,調用方法跟普通的QML類型同樣。
二、把C++類註冊爲一個單例類型,能夠在QML中導入單例對象實例
三、把C++類做爲上下文屬性或者上下文對象嵌入到QML中網絡

在啓動QML時,會初始化一個QQmlEngine做爲QML引擎,而後使用QQmlComponent對象加載QML文檔,QML引擎會提供一個默認的QQmlContext對象做爲頂層執行的上下文,用來執行QML文檔中定義的函數和表達式。
QQmlEngine::rootContext() 返回當前引擎QML的上下文,惟一的,QQmlContext* QQuickView::rootContext()
QQuickItem* QQuickView::rootObject() 返回當前QQuickView的根節點,也就是QML的根節點架構

QQmlEngine
QQmlEngine類提供了一個QML引擎,用於管理由QML文檔定義的對象層次架構,QML提供了一個默認的QML上下文(根上下文,獲取函數QQmlEngine::rootContext())。該上下文是QML表達式的執行環境,而且保證在使用時對象屬性可以被正確更新。
QQmlEngine能夠將全局設置應用到其管理下的全部QML對象,好比網絡通訊:QNetworkAccessManager、全局永久(整個程序生命週期)存儲的文件路徑(資源預加載)等函數

QQmlContext
QQmlContext提供了對象實例化和表達式執行所須要的上下文環境。全部的QML對象都要在特定的上下文中實例化,全部的表達式都要在特定的上下文中執行。上下文以根上下文爲主組成層次結構,子上下文繼承父上下文的屬性,修改子上下文的屬性值能夠覆蓋父上下文的屬性值。
QQmlContext::setContextProperty()可以經過名字將數據顯示綁定到上下文,定義、更新上下文的屬性
【注意】使用QQmlContext::setContextProperty()顯示設置對象的屬性會優先於上下文對象的屬性性能

QQmlComponent
QML文檔定義的對象類型能夠在運行時使用QQmlComponent類進行實例化,QQmlComponent封裝了QML組件(component)的定義,能夠用於加載QML文檔,前提條件是須要QQmlEngine實例化QML文檔中定義的對象層次結構。
QQmlComponent實例既可使用C++直接建立,也能夠經過Qt.createComponent()函數在QML代碼中建立ui

QQmlExpression
 動態執行表達式QQmlExpression容許客戶端,在C++中利用一個特定的QML上下文執行JavaScript表達式,表達式執行的結果以QVariant的形式返回,而且遵照QML引擎肯定的轉換規則。.net


2、在QML中使用C++特性
因爲QML引擎與Qt元對象系統的緊密集成,QML能夠直接訪問QObject子類的屬性、方法、信號等。
一、QML能夠直接讀取和修改C++的屬性
二、QML能夠經過JavaScript直接調用C++方法
三、QML能夠接收C++的信號
因爲QML和C++二者運行所須要的上下文環境不一樣,當QML訪問C++數據時,數據的全部權還在C++,特例:就是一個顯示的C++函數調用而且返回QObject類型,QML引擎訪問獲取數據的全部權。Qt提供了兩種在QML訪問C++的方法:
法1:在C++中建立一個類,註冊爲QML環境的一個類型,在QML中就可使用這個類建立對象進行訪問。
法2:在C++構建一個對象,把對象經過QQmlContext::setContextProperty()設置到QML的上下文,在QML中可直接使用該對象。component

一、把C++建立的類設置到QML上下文
類的要求:(1)QObject類或繼承QObject。(2)調用宏Q_OBJECT。這樣的類可以進入Qt元對象系統,也會被QML訪問。如下是QML常常訪問的C++類型
(1)QML訪問C++信號、槽
例子:
建立類:                                                                把類加入QML上下文:                                                                              QML中訪問C++類
class MakeClass : public QObject                        QQmlEngine engine;                                                                               text = qml_make.SetStr("Hello for QML!!!");
{                                                                             MakeClass Cmake;   //類對象,在下邊設置上下文                                   qml_make.SlotMake();
    Q_OBJECT                                                         engine.rootContext->setContextProperty("qml_make",&Cmake)
    public:
         Q_INVOKABLE void SetStr(QString str);對象

    signals:   //C++信號
          void MakeSignal(QString str);blog

    public slots:  //C++槽函數
          void SlotMake();
};繼承

(2)Q_INVOKABLE 宏修飾函數,會註冊到Qt元對象系統中,QML能夠直接訪問 ${Object}.${method}
定義函數:Q_INVOKABLE void SetStr(QString str);
QML中使用函數:text = qml_make.SetStr("Hello for QML!!!");

(3)Q_ENUMS 宏修飾枚舉,會註冊到Qt元對象系統中,QML能夠直接訪問 ${Object}.${method}
定義枚舉:Q_ENUMS(m_enum);
QML中使用枚舉:text = qml_make.m_enum;

(4)Q_PROPERTY 宏修飾屬性,會註冊到Qt元對象系統中,QML能夠對屬性進行訪問、修改、屬性改變發送信號等操做。
定義屬性:Q_PROPERTY(QString Test                //定義一個QString類型的Text屬性
                                             READ GetTest         //定義讀操做                                                  
                                             WRITE SetText        //定義寫操做
                                             NOTIFY SlotTextChanged      //定義關聯信號,當屬性發生改變時,觸發信號
)
QML中使用屬性:text = qml_make.GetText;    //調用C++中Text屬性的讀操做
                         Component.onCompleted: {
                               qml_make.SetText = "Text for QML"    //調用C++中Text屬性的寫操做
                                      }  


二、把C++對象註冊到QML中,當作一個QML對象
QObject 類或 QObject 子類均可以註冊到QML中,在QML中當作一個對象類型進行實例化
註冊QML類型有多個方法:
(1)qmlRegisterSingletonType()            註冊一個單例類型
(2)qmlRegisterType()                             註冊一個非單例類型
(3)qmlRegisterTypeNotAvailaible()      註冊一個類型用來佔位
(4)qmlRegisterUncreatableType()        註冊一個具備附加屬性類型

例子:
(1)建立類:                                                                                                                                              
class MakeClass : public QObject                                                                                                       
{                                                                                                              
    Q_OBJECT                                                         
    public:                                                               
         Q_INVOKABLE void SetStr(QString str);

         Q_PROPERTY(QString Test                //定義一個QString類型的Text屬性
                                             READ GetTest         //定義讀操做                                                  
                                             WRITE SetText        //定義寫操做
                                             NOTIFY SlotTextChanged      //定義關聯信號,當屬性發生改變時,觸發信號

    signals:   //C++信號
          void MakeSignal(QString str);

    public slots:  //C++槽函數
          void SlotMake();
};

(2)在main函數把類註冊到QML中,註冊函數要放到QML上下文建立以前,不然註冊不成功:
qmlRegisterType<MakeClass>("For.Qt.MakeClass" , 1, 0, "MakeClassQml");      //把類MakeClass註冊到QML中的包爲:For.Qt.MakeClass, 版本:1.0, 類型爲:MakeClassQml
QQuickView view; 
view.setSource( QUrl(QStringLiteral("qrc:///main.qml")));  
view.show();  

(3)QML引入而且訪問C++對象類型
import For.Qt.MakeClass 1.0 
Item
{
    MakeClassQml{                   
          SetText : "Hello for QML"   //C++屬性的寫操做
    }
}

———————————————— 版權聲明:本文爲CSDN博主「西_瓜_瓜」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。 原文連接:https://blog.csdn.net/xi_gua_gua/article/details/56991367

相關文章
相關標籤/搜索