青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆 - 30  文章 - 67  trackbacks - 0
<2025年9月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

常用鏈接

留言簿(8)

隨筆分類

隨筆檔案

文章檔案

收藏夾

Oops

搜索

  •  

積分與排名

  • 積分 - 86331
  • 排名 - 277

最新評論

閱讀排行榜

評論排行榜

簡介

本文主要講解Qt是如何實(shí)現(xiàn)反射,以及一點(diǎn)點(diǎn)反射使用的小心得。

文章概覽

Qt反射內(nèi)幕小窺

詳細(xì)內(nèi)容

反射前期準(zhǔn)備

得到注冊的類成員變量

得到注冊的類成員函數(shù)

訪問類成員屬性(get,set)

調(diào)用注冊的函數(shù)

反射應(yīng)用

總結(jié)

Qt反射內(nèi)幕小窺

Qt反射機(jī)制是基于moc(meta object compiler)實(shí)現(xiàn)的,在這里多插一句(可以說Qt所有C++沒有的特性,幾乎都和這個(gè)有關(guān)系)。但是需要注意的是Qt提供的反射式基本的反射,不支持類的反射,這個(gè)與Java,C#還是有差別的。

moc講解

通常C++的編譯過程為

預(yù)處理->編譯->鏈接->運(yùn)行

Qt編譯的過程中,有一個(gè)moc的過程,在Qt工程構(gòu)建過程中的qmake其實(shí)就是干這個(gè)事的。moc->預(yù)處理->編譯->鏈接->運(yùn)行。

在moc過程中,需要處理的事情如下:

1、 識別一些特殊的宏Q_OBJECT、Q_PROPERTY、Q_INVOKABLE。。。; 如果碰到這些關(guān)鍵字,Qt自然就會去生成對應(yīng)的moc文件。

2、 slot,signal自然也是如此。

3、 uidesigner,同樣也是在這個(gè)階段處理的;

詳細(xì)內(nèi)容

 

反射前期準(zhǔn)備

1、 首先得繼承于Q_Object,同時(shí)需要在class中加入Q_OBJECT,但是Q_Object的構(gòu)造函數(shù)默認(rèn)是私有的不讓繼承。

在類中直接使用Q_GADGET也可以實(shí)現(xiàn)反射,。。。據(jù)說只能實(shí)現(xiàn)部分功能,目前我只實(shí)現(xiàn)到能遍歷成員屬性,函數(shù),但是不能訪問其中的值。

這個(gè)過程其實(shí)就是定義QMetaObject的過程,具體見Qt源碼

2、 注冊類成員變量需要使用Q_PROPERTY

Q_PROPERTY( type member READ get WRITE set) 其中READ,WRITE是關(guān)鍵字

Type表示成員的類型(不支持自定義類型,對Qt很多基本類型都支持);

Member代表你給該成員另外起的名字,可以和變量名不同;get,set就是自己在C++函數(shù)里面定義的基本的訪問函數(shù)名,不需要寫參數(shù)。直接上代碼:

3、 注冊類成員函數(shù)

如果你希望這個(gè)函數(shù)能夠被反射,那么很簡單,只需要在類的函數(shù)聲明前加入Q_INVOKABLE關(guān)鍵字。

例如Q_INVOKABLE int func( QString flag );

   #include <QObject>
   class MyClass : public QObject
   {
    Q_OBJECT
    Q_PROPERTY(int Member1 READ Member1 WRITE setMember1 )
    Q_PROPERTY(int Member2 READ Member2 WRITE setMember2 )
    Q_PROPERTY(QString MEMBER3 READ Member3 WRITE setMember3 )
   public:
    explicit MyClass(QObject *parent = 0);
   signals:
   public slots:
   public:
    Q_INVOKABLE int Member1();
    Q_INVOKABLE int Member2();
    Q_INVOKABLE QString Member3();
    Q_INVOKABLE void setMember1( int mem1 );
    Q_INVOKABLE void setMember2( int mem2 );
    Q_INVOKABLE void setMember3( const QString& mem3 );
    Q_INVOKABLE int func( QString flag );
   private:
    int m_member1;
    int m_member2;
    QString m_member3;
   };

得到注冊的類成員變量

  MyClass theObj;
 const QMetaObject* metaObj = theObj.metaObject();
 //1.遍歷類的屬性
 int propertyCnt = metaObj->propertyCount();
 for ( int i = 0; i < propertyCnt; ++ i )
 {
 QMetaProperty oneProperty = metaObj->property( i );
 cout << " name: " << oneProperty.name();
 cout << " type: " << QVariant::typeToName( oneProperty.type()) << "\n";
  }

主要思路就是得到其元對象,得到其元屬性,然后就能得到你需要的信息,具體的訪問函數(shù)有name,type,需要注意的是得到的type是枚舉值,還在Qt提供了typeToName的函數(shù),你可以得到想要的(例如不是空洞的2,而是”int”)。

得到注冊的類成員函數(shù)

//2.遍歷類的函數(shù)成員
 int methodCnt = metaObj->methodCount();
 for ( int idx = 0; idx < methodCnt; ++ idx )
 {
 QMetaMethod oneMethod = metaObj->method( idx );
 cout << "--------begin-------" << "\n";
 cout << " typeName: " << oneMethod.typeName() << "\n";
 cout << " signature: " << oneMethod.signature() << "\n";
 cout << " methodType: " << oneMethod.methodType() << "\n";
 cout << "--------end---------" << "\n";
  }

和遍歷類屬性一致,其實(shí)就是根據(jù)元對象,得到元函數(shù);

其中typeName代表返回類型,signature只的是函數(shù)的原貌,methodType代表函數(shù)的類型,在Qt中分為三類(槽,信號,普通函數(shù))。

訪問類成員屬性(get,set)

//3.使用反射
 cout << "-------test property-----------" << "\n";
 MyClass newObj;
 newObj.setProperty("Member1", 66);
 cout << newObj.property( "Member1" ).toString().toStdString() << "\n";
 cout << newObj.Member1() << "\n";
 cout << "--------end----------" << "\n";

在這里使用的是QObject的property() 和setProperty方法,來訪問成員信息。但是對于使用Q_GADGET宏的類,是不能使用這個(gè)方法的,還在尋找解決方法,基本思路當(dāng)然是重寫。

調(diào)用注冊的函數(shù)

  int ret;
  MyClass newObj;
 newObj.setMember1( 20 );
 newObj.setMember2( 50 );
 QMetaObject::invokeMethod( &newObj, "func", Qt::DirectConnection,
 Q_RETURN_ARG(int, ret ),
 Q_ARG(QString, "+"));

//普通函數(shù)的調(diào)用

在MyClass中,我們定義了int func( QString flag );這個(gè)函數(shù),利用反射的調(diào)用方式如上,主要是理解invokeMethod的用法,其中Qt::DirectConnection是函數(shù)的執(zhí)行方式,分為(異步和同步),Q_RETURN_ARG是返回參數(shù),Q_ARG是傳入?yún)?shù),需要按函數(shù)聲明中參數(shù)的順序依次傳入,Qt最多支持9個(gè)參數(shù),對于一般的應(yīng)用沒有問題。還有疑問,請移步具見Qt強(qiáng)大的幫助文檔。

反射的應(yīng)用

反射反射,就我目前的認(rèn)知水平來看,通過使用字符串,來實(shí)現(xiàn)函數(shù)的通用化調(diào)用,例如你可以利用反射把很多函數(shù)放置到數(shù)組中,實(shí)現(xiàn)一次遍歷,全部調(diào)用。

目前我見到的大多是利用反射來操作數(shù)據(jù)庫,例如hibernate,其實(shí)可以利用Qt的反射,快速實(shí)現(xiàn)所謂的hibernate,(最近自己獨(dú)立實(shí)現(xiàn)了一套,很方便)。

總結(jié)

這篇文章主要講了如何使用Qt來實(shí)現(xiàn)反射,在實(shí)用角度上來講,我們不需要了解Qt是怎么實(shí)現(xiàn)反射的,對于怎么用上面說的很清楚了。大家有什么的新的想法,希望能提出來,來電請咨詢
<levard@gmail.com>

posted on 2013-07-13 22:19 Cunch 閱讀(14466) 評論(1)  編輯 收藏 引用 所屬分類: C++Qt

FeedBack:
# re: Qt反射 2013-07-17 17:01 tb
發(fā)射總結(jié)不出  回復(fù)  更多評論
  
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
      <noscript id="pjuwb"></noscript>
            <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
              <dd id="pjuwb"></dd>
              <abbr id="pjuwb"></abbr>
              亚洲欧美日韩国产成人| 国产自产2019最新不卡| 夜夜嗨av色一区二区不卡| 麻豆精品视频在线| 蜜桃久久精品一区二区| 亚洲人妖在线| 欧美日韩精品免费看| 韩国一区二区在线观看| 欧美资源在线观看| 久久综合中文| 亚洲视频专区在线| 欧美一区二区三区喷汁尤物| 依依成人综合视频| 亚洲国产高清视频| 欧美日韩在线视频一区二区| 欧美在线free| 欧美成人一区二区| 性8sex亚洲区入口| 久久影院午夜片一区| 亚洲视频狠狠| 久久久久九九九九| 亚洲欧美日本日韩| 免费久久99精品国产自| 亚洲一区在线免费观看| 久久久久久久久久码影片| 一区二区三区欧美成人| 久久精品盗摄| 午夜在线播放视频欧美| 欧美成人国产一区二区| 久久精品日韩欧美| 欧美日韩国产在线一区| 美玉足脚交一区二区三区图片| 欧美另类高清视频在线| 久久中文在线| 国产拍揄自揄精品视频麻豆| 亚洲精品1区2区| 在线观看欧美激情| 午夜日韩激情| 亚洲一区二区伦理| 欧美精品久久久久久久久久| 久久久另类综合| 国产伦精品一区二区三区视频黑人 | 欧美日韩综合另类| 欧美国产在线电影| 激情久久综艺| 欧美一级理论性理论a| 亚洲欧美另类久久久精品2019| 麻豆乱码国产一区二区三区| 久久久精品tv| 国产日韩精品综合网站| 亚洲一区免费网站| 亚洲欧美视频在线观看视频| 欧美精品二区| 亚洲精品久久嫩草网站秘色| 亚洲国产精品va在看黑人| 久久成人18免费观看| 欧美在线精品免播放器视频| 国产精品第2页| 99国产精品视频免费观看| 99在线热播精品免费| 欧美激情一区二区三区在线视频观看 | 欧美色综合天天久久综合精品| 亚洲高清在线精品| 亚洲老板91色精品久久| 欧美成人tv| 亚洲美女av在线播放| 99综合电影在线视频| 欧美日本久久| 免费欧美网站| 国模精品一区二区三区| 国产欧美亚洲一区| 亚洲午夜在线| 一本一本a久久| 亚洲女同精品视频| 久久av一区二区| 国产私拍一区| 久久精品国产免费看久久精品| 久久精品中文字幕免费mv| 国外成人网址| 欧美 日韩 国产精品免费观看| 欧美激情成人在线| 亚洲视频在线二区| 国产乱人伦精品一区二区| 久久se精品一区二区| 欧美国产日韩一区| 一区二区日韩伦理片| 国产精品日本| 久久久精品日韩欧美| 亚洲激情视频| 午夜精品视频在线观看| 尤物精品在线| 欧美性色视频在线| 久久精品国产77777蜜臀| 亚洲国产精品嫩草影院| 亚洲欧美日韩综合国产aⅴ| 国产原创一区二区| 欧美精品一区二区三区在线看午夜 | 午夜日韩在线观看| 1024亚洲| 国产精品自拍网站| 免费美女久久99| 亚洲欧美亚洲| 最新高清无码专区| 欧美在线日韩在线| 亚洲精品乱码久久久久久久久| 国产精品美女久久久久aⅴ国产馆| 久久大香伊蕉在人线观看热2| 亚洲欧洲在线一区| 久久三级福利| 亚洲女与黑人做爰| 亚洲精品系列| 狠狠色综合日日| 国产精品青草综合久久久久99| 美女脱光内衣内裤视频久久影院 | 亚洲国产综合在线看不卡| 久久精品免费电影| 正在播放日韩| 亚洲人妖在线| 在线观看免费视频综合| 国产日韩欧美一区在线 | 欧美色区777第一页| 久久免费精品日本久久中文字幕| 亚洲一区二区影院| 一区二区三区**美女毛片| 亚洲福利在线看| 欧美aaaaaaaa牛牛影院| 久久免费视频一区| 久久国产精品电影| 亚洲欧美日韩久久精品| 欧美一级精品大片| 亚洲无毛电影| 一本大道久久a久久精品综合| 亚洲福利在线观看| 伊人久久亚洲热| 一区二区在线观看视频在线观看| 国产女人aaa级久久久级| 国产精品福利片| 国产精品久久久久久亚洲毛片| 欧美日韩大陆在线| 欧美日韩在线视频观看| 欧美三级电影网| 欧美午夜大胆人体| 国产精品福利久久久| 国产精品久久久久久久久久尿 | 国产一区视频网站| 国内一区二区三区在线视频| 国户精品久久久久久久久久久不卡| 国产色视频一区| 黄色成人91| 亚洲高清视频的网址| 亚洲精品久久久一区二区三区| 亚洲欧洲美洲综合色网| 夜夜嗨网站十八久久| 在线亚洲一区观看| 欧美在线观看日本一区| 久久精品免费播放| 欧美国产极速在线| 亚洲日本在线观看| 亚洲视屏一区| 久久久噜噜噜久久中文字免| 麻豆成人综合网| 欧美日韩在线免费| 国产日韩欧美亚洲一区| 亚洲国产高清aⅴ视频| 亚洲日本成人网| 午夜精品一区二区三区在线| 久久久久久久久伊人| 亚洲电影视频在线| 亚洲一区欧美一区| 久久亚洲不卡| 国产精品家庭影院| 樱花yy私人影院亚洲| 日韩视频在线一区二区三区| 午夜精品一区二区三区电影天堂| 久久在精品线影院精品国产| 亚洲激情综合| 欧美在线看片| 欧美日韩免费精品| 激情综合激情| 亚洲自拍16p| 亚洲国产精品黑人久久久 | 亚洲国产第一| 亚洲欧美另类综合偷拍| 欧美**人妖| 国产一级久久| 国产精品99久久久久久www| 久久精品视频在线| 亚洲精品欧美日韩专区| 久久精品色图| 国产精品自拍网站| 中文av字幕一区| 欧美激情一区二区三区成人| 亚洲欧美日韩一区二区三区在线| 欧美成人综合网站| 精品va天堂亚洲国产| 翔田千里一区二区| 日韩视频―中文字幕| 欧美风情在线| 在线观看欧美成人| 久热精品视频在线观看一区|