亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Q_INVOKABLE與invokeMethod用法全解

系統 4995 0



Qt/Qt Quick宏淺議 一文中,我們將介紹Qt中經常使用的幾個宏: Q_OBJECT, SIGNAL與SLOT, Q_SIGNALS 與 Q_SLOTS, Q_EMIT ,Q_INVOKABLE, Q_PROPERTY。相比其他宏,Q_INVOKABLE 顯得更加神秘,但Q_INVOKABLE的理解與使用變得越來越重要。本文將圍繞Q_INVOKABLE以及相對應的invokeMethod展開討論。

Q_INVOKABLE

#define Q_INVOKABLE

重新回顧一下Q_INVOKABLE的定義,它在$QTDIR/src/corelib/kernel/qobjectdefs.h 中,簡單被define,目的在于讓moc識別。

使用Q_INVOKABLE來修飾成員函數,目的在于被修飾的成員函數能夠被元對象系統所喚起。

QMetaObject::invokeMethod

靜態(tài)方法QMetaObject::invokeMethod() 的定義如下:

    1. bool QMetaObject::invokeMethod(QObject*obj, const char *member,Qt::ConnectionTypetype,
    2. QGenericReturnArgumentret,QGenericArgumentval0=QGenericArgument(0),…)

invokeMethod的用法為,嘗試調用對象obj的方法member(注意member可以為信號或者是槽),如何member可以被調用,則返回真,否則返回假。QMetaObject::invokeMethod可以是異步調用,也可以是同步調用。這取決與它的連接方式Qt::ConnectionType type。如果type為Qt::DirectConnection,則為同步調用,若為Qt::QueuedConnection,則為異步調用。例如:

    1. QMetaObject::invokeMethod(object, "methodName" ,
    2. Qt::QueuedConnection,
    3. Q_ARG(type1,arg1),
    4. Q_ARG(type2,arg2));

上述調用為異步調用。請注意,因為上面所示的參數需要被在構建事件時進行硬拷貝,參數的自定義型別所對應的類需要提供一個共有的構造函數、析構函數以及拷貝構造函數。而且必須使用注冊Qt型別系統所提供的qRegisterMetaType() 方法來注冊這一自定義型別。

Q_INVOKABLE與QMetaObject::invokeMethod均由元對象系統喚起。這一機制在 Qt C++/QML混合編程 跨線程編程 Qt Service Framework 以及Qt/ HTML5混合編程 以及里廣泛使用。

Qt C++/QML混合編程

QML中調用C++方法借助了Qt元對象系統。考慮在QML中使用Qt C++定義的方法,如下代碼所示:

  1. importQt4.7
  2. importShapes5.0 //自定義模塊
  3. Item{
  4. width:300;height:200
  5. Ellipse{
  6. x:50;y:35;width:200;height:100
  7. color: "blue"
  8. MouseArea{
  9. anchors.fill:parent
  10. //調用C++中定義的randomColor方法
  11. onClicked:parent.color=parent.randomColor()
  12. }
  13. }
  14. }

為了讓上述QML代碼成功的調用下面這段代碼定義的randomColor()函數,最為關鍵的一點見randomColor方法用Q_INVOKABLE 修飾。

  1. #include<QDeclarativeItem>
  2. class EllipseItem: public QDeclarativeItem
  3. {
  4. Q_OBJECT
  5. public
  6. Q_INVOKABLEQColorrandomColor() const ;

更多細節(jié),請參看我的另一篇博文: QML與C++混合編程使用

在跨線程編程中的使用

我們如何調用駐足在其他線程里的QObject方法呢?Qt提供了一種非常友好而且干凈的解決方案:向事件隊列post一個事件,事件的處理將以調用我們所感興趣的方法為主(當然這需要線程有一個正在運行的事件循環(huán))。而觸發(fā)機制的實現是由moc提供的內省方法實現的。因此,只有信號、槽以及 被標記成Q_INVOKABLE的方法才能夠被其它線程所觸發(fā)調用 。如果你不想通過跨線程的信號、槽這一方法來實現調用駐足在其他線程里的QObject方法。另一選擇就是將方法聲明為Q_INVOKABLE,并且在另一線程中用 invokeMethod 喚起。

更多細節(jié),譯文 事件循環(huán)與線程

Qt Service Framework

Qt服務框架是Qt Mobility 1.0.2版本推出的,一個服務(service)是一個獨立的組件提供給客戶端(client)定義好的操作。客戶端可以通過服務的名稱,版本號和服務的對象提供的接口來查找服務。 查找到服務后,框架啟動服務并返回一個指針。

服務通過插件(plug-ins)來實現。為了避免客戶端依賴某個具體的庫,服務必須繼承自QObject。這樣 QMetaObject 系統可以用來提供動態(tài)發(fā)現和喚醒服務的能力。要使QmetaObject機制充分的工作,服務必須滿足,其所有的方法都是通過 signal,slot,property 或 invokable method Q_INVOKEBLE 來實現

其中,最常見的與servicer交互的方法如下:

      
  1. QServiceManagermanager;QObject*storage;
  2. storage=manager.loadInterface( "com.nokia.qt.examples.FileStorage" ); if (storage)QMetaObject::invokeMethod(storage, "deleteFile" ,Q_ARG(QString, "/tmp/readme.txt" ));
      上面的代碼通過service的元對象提供的invokeMethod方法,調用文件存儲對象的deleteFile() 方法。客戶端不需要知道對象的類型,因此也沒有鏈接到具體的service庫。 當然在服務端的deleteFile方法,一定要被標記為
      
        Q_INVOKEBLE,
      
      才能夠被元對象系統識別
    

Qt服務框架的一個亮點是它支持 跨進程通信 ,服務可以接受遠程進程。在服務管理器上注冊后 進程通過signal,slot, invokable method 和property來通信,就像本地對象一樣。服務可以設定為在客戶端間共享,或針對一個客戶端。 請注意 ,在Qt服務框架推出之前,信號、槽以及invokable method僅支持跨線程。 下圖是跨進成的服務/客戶段通信示意圖(圖片來自諾基亞論壇)。這里我們可以清楚的看到, invokable method Q_INVOKEBLE 是跨進城、跨線程對象之間通信的重要利器。

serivceFramework

有關Qt Service Framework的更多討論和用例,請參見 Qt Service Framework文檔

請尊重原創(chuàng)作品和譯文。轉載請保持文章完整性,并以超鏈接形式注明原始作者 地址 http://blog.csdn.net/changsheng230 ,方便其他朋友提問和指正。


Qt/Qt Quick宏淺議 一文中,我們將介紹Qt中經常使用的幾個宏: Q_OBJECT, SIGNAL與SLOT, Q_SIGNALS 與 Q_SLOTS, Q_EMIT ,Q_INVOKABLE, Q_PROPERTY。相比其他宏,Q_INVOKABLE 顯得更加神秘,但Q_INVOKABLE的理解與使用變得越來越重要。本文將圍繞Q_INVOKABLE以及相對應的invokeMethod展開討論。

Q_INVOKABLE

#define Q_INVOKABLE

重新回顧一下Q_INVOKABLE的定義,它在$QTDIR/src/corelib/kernel/qobjectdefs.h 中,簡單被define,目的在于讓moc識別。

使用Q_INVOKABLE來修飾成員函數,目的在于被修飾的成員函數能夠被元對象系統所喚起。

QMetaObject::invokeMethod

靜態(tài)方法QMetaObject::invokeMethod() 的定義如下:

    1. bool QMetaObject::invokeMethod(QObject*obj, const char *member,Qt::ConnectionTypetype,
    2. QGenericReturnArgumentret,QGenericArgumentval0=QGenericArgument(0),…)

invokeMethod的用法為,嘗試調用對象obj的方法member(注意member可以為信號或者是槽),如何member可以被調用,則返回真,否則返回假。QMetaObject::invokeMethod可以是異步調用,也可以是同步調用。這取決與它的連接方式Qt::ConnectionType type。如果type為Qt::DirectConnection,則為同步調用,若為Qt::QueuedConnection,則為異步調用。例如:

    1. QMetaObject::invokeMethod(object, "methodName" ,
    2. Qt::QueuedConnection,
    3. Q_ARG(type1,arg1),
    4. Q_ARG(type2,arg2));

上述調用為異步調用。請注意,因為上面所示的參數需要被在構建事件時進行硬拷貝,參數的自定義型別所對應的類需要提供一個共有的構造函數、析構函數以及拷貝構造函數。而且必須使用注冊Qt型別系統所提供的qRegisterMetaType() 方法來注冊這一自定義型別。

Q_INVOKABLE與QMetaObject::invokeMethod均由元對象系統喚起。這一機制在 Qt C++/QML混合編程 跨線程編程 Qt Service Framework 以及Qt/ HTML5混合編程 以及里廣泛使用。

Qt C++/QML混合編程

QML中調用C++方法借助了Qt元對象系統。考慮在QML中使用Qt C++定義的方法,如下代碼所示:

  1. importQt4.7
  2. importShapes5.0 //自定義模塊
  3. Item{
  4. width:300;height:200
  5. Ellipse{
  6. x:50;y:35;width:200;height:100
  7. color: "blue"
  8. MouseArea{
  9. anchors.fill:parent
  10. //調用C++中定義的randomColor方法
  11. onClicked:parent.color=parent.randomColor()
  12. }
  13. }
  14. }

為了讓上述QML代碼成功的調用下面這段代碼定義的randomColor()函數,最為關鍵的一點見randomColor方法用Q_INVOKABLE 修飾。

  1. #include<QDeclarativeItem>
  2. class EllipseItem: public QDeclarativeItem
  3. {
  4. Q_OBJECT
  5. public
  6. Q_INVOKABLEQColorrandomColor() const ;

更多細節(jié),請參看我的另一篇博文: QML與C++混合編程使用

在跨線程編程中的使用

我們如何調用駐足在其他線程里的QObject方法呢?Qt提供了一種非常友好而且干凈的解決方案:向事件隊列post一個事件,事件的處理將以調用我們所感興趣的方法為主(當然這需要線程有一個正在運行的事件循環(huán))。而觸發(fā)機制的實現是由moc提供的內省方法實現的。因此,只有信號、槽以及 被標記成Q_INVOKABLE的方法才能夠被其它線程所觸發(fā)調用 。如果你不想通過跨線程的信號、槽這一方法來實現調用駐足在其他線程里的QObject方法。另一選擇就是將方法聲明為Q_INVOKABLE,并且在另一線程中用 invokeMethod 喚起。

更多細節(jié),譯文 事件循環(huán)與線程

Qt Service Framework

Qt服務框架是Qt Mobility 1.0.2版本推出的,一個服務(service)是一個獨立的組件提供給客戶端(client)定義好的操作。客戶端可以通過服務的名稱,版本號和服務的對象提供的接口來查找服務。 查找到服務后,框架啟動服務并返回一個指針。

服務通過插件(plug-ins)來實現。為了避免客戶端依賴某個具體的庫,服務必須繼承自QObject。這樣 QMetaObject 系統可以用來提供動態(tài)發(fā)現和喚醒服務的能力。要使QmetaObject機制充分的工作,服務必須滿足,其所有的方法都是通過 signal,slot,property 或 invokable method Q_INVOKEBLE 來實現

其中,最常見的與servicer交互的方法如下:

    
  1. QServiceManagermanager;QObject*storage;
  2. storage=manager.loadInterface( "com.nokia.qt.examples.FileStorage" ); if (storage)QMetaObject::invokeMethod(storage, "deleteFile" ,Q_ARG(QString, "/tmp/readme.txt" ));
    上面的代碼通過service的元對象提供的invokeMethod方法,調用文件存儲對象的deleteFile() 方法。客戶端不需要知道對象的類型,因此也沒有鏈接到具體的service庫。 當然在服務端的deleteFile方法,一定要被標記為
    
      Q_INVOKEBLE,
    
    才能夠被元對象系統識別
  

Qt服務框架的一個亮點是它支持 跨進程通信 ,服務可以接受遠程進程。在服務管理器上注冊后 進程通過signal,slot, invokable method 和property來通信,就像本地對象一樣。服務可以設定為在客戶端間共享,或針對一個客戶端。 請注意 ,在Qt服務框架推出之前,信號、槽以及invokable method僅支持跨線程。 下圖是跨進成的服務/客戶段通信示意圖(圖片來自諾基亞論壇)。這里我們可以清楚的看到, invokable method Q_INVOKEBLE 是跨進城、跨線程對象之間通信的重要利器。

serivceFramework

有關Qt Service Framework的更多討論和用例,請參見 Qt Service Framework文檔

請尊重原創(chuàng)作品和譯文。轉載請保持文章完整性,并以超鏈接形式注明原始作者 地址 http://blog.csdn.net/changsheng230 ,方便其他朋友提問和指正。

Q_INVOKABLE與invokeMethod用法全解


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 最新国产精品久久精品 | 精品久久久久久中文字幕2017 | 亚洲国产品综合人成综合网站 | 911国产视频 | 狠狠色伊人亚洲综合第8页 狠狠色综合久久丁香婷婷 狠狠色综合久久婷婷 | 国产精品成人观看视频免费 | 国产亚洲精品自在线观看 | 国内夫妇精品对白在线播放 | 亚洲精品人成网线在线 | 四虎在线永久精品高清 | 国产一区二区三区在线观看精品 | 国产成人经典三级在线观看 | 福利影院在线 | 综合爱爱网| 麻豆国产在线观看一区二区 | a一区二区三区视频 | 俄罗斯色视频 | 亚洲欧美日韩精品 | 特级毛片免费观看视频 | 怡红院成人永久免费看 | 99九九精品国产高清自在线 | 国产在线视频不卡 | 久久riav国产精品 | 偷拍肉窝窝视频在线播放 | 国产成人久久一区二区三区 | 香蕉视频网站在线播放 | 每日更新在线观看av | 夜夜天天操| 久久福利青草精品资源站免费 | 天天干天天做天天操 | 老司机亚洲精品影视www | 成人久久视频 | 亚洲欧洲国产精品 | 四虎午夜剧场 | 成人嫩草研究院网站进 | 国产欧美曰韩一区二区三区 | 免费99| 一级毛片在线看在线播放 | 精品无人区乱码1区2区3区在线 | 殴美一级片 | 日韩欧美色 |