• <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>
            posts - 319, comments - 22, trackbacks - 0, articles - 11
              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

            Qt/Qt Quick宏淺議

            Posted on 2011-08-05 07:16 RTY 閱讀(844) 評論(0)  編輯 收藏 引用 所屬分類: QtQML

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

             

            剛開始接觸Qt的朋友可能對Qt在使用當(dāng)中需要聲明的各色各樣的宏感到神秘而又陌生,本文將介紹Qt中經(jīng)常使用的幾個宏: Q_OBJECT, SIGNAL與SLOT, Q_SIGNALS 與 Q_SLOTS, Q_EMIT ,Q_INVOKABLE, Q_PROPERTY:

             

            宏的頭文件出處: $QTDIR/src/corelib/kernel/qobjectdefs.h

            Q_OBJECT

            #define Q_OBJECT / 
            public: / 
                Q_OBJECT_CHECK / 
                static const QMetaObject staticMetaObject; / 
                Q_OBJECT_GETSTATICMETAOBJECT / 
                virtual const QMetaObject *metaObject() const; / 
                virtual void *qt_metacast(const char *); / 
                QT_TR_FUNCTIONS / 
                virtual int qt_metacall(QMetaObject::Call, int, void **); /

            宏Q_OBJECT是Qt所有宏中最為重要的一個,Q_OBJECT是使用信號槽機制以及其他所有元對象系統(tǒng)提供的服務(wù)(內(nèi)省、invokeMethod,元對象property系統(tǒng)等等)的前提條件。有關(guān)Q_OBJECT的討論請參考Qt源碼分析之QObject。 

            SIGNAL與SLOT

            這兩個宏是調(diào)用connect方法時用到:

             

            1. QObject::connect(myButton, SIGNAL(clicked()),   
            2.                   label,  SLOT(showText()));  
             

             

            那么宏SIGNAL和SLOT為我們做了那些事情呢,看一下源代碼:

             

            1. $QTDIR/src/corelib/kernel/qobjectdefs.h  
            2. # define SLOT(a)     qFlagLocation("1"#a QLOCATION)   
            3. # define SIGNAL(a)   qFlagLocation("2"#a QLOCATION)  
            4. $QTDIR/src/corelib/kernel/qobject.cpp  
            5. const char *qFlagLocation(const char *method)   
            6. {   
            7.     static int idx = 0;   
            8.     flagged_locations[idx] = method;   
            9.     idx = (idx+1) % flagged_locations_count;   
            10.     return method;   
            11. }  
             

             

            原來它會基于把我們定義的信號、槽的名稱返回一個字符串,比如SIGNAL(clicked()) 返回字符串 “2clicked()”, SLOT(showText())返回字符串“1showText()”

            1. Q_SIGNALS 與 Q_SLOTS  
            2. #  define slots   
            3. #  define signals protected   
            4. # define Q_SLOTS   
            5. # define Q_SIGNALS protected  
             

             

            Q_SIGNALS 與 Q_SLOTS是Qt 4.1引入的,它們用來替換關(guān)鍵字signals和slots,原因是更好的與第三方信號槽機制兼容,比如boost庫。盡管Q_SIGNALS 與 Q_SLOTS看起來沒有做什么。其實不然,QT的元對象編譯器moc會識別聲明在頭文件中的宏Q_SIGNALS,Q_SLOTS。并做為依據(jù),生成元對象模型數(shù)據(jù),詳見文中最后所示代碼實例

            Q_EMIT

            #define Q_EMIT #define emit

            Q_EMIT用來替換關(guān)鍵字emit,原因也是更好的與第三方信號槽機制兼容,比如boost庫。

            這里要注意,我們看到Q_EMIT看起來同樣的簡單, 但它們是有區(qū)別的!表面的區(qū)別在于Q_SIGNALS 與 Q_SLOTS用在頭文件中,而Q_EMIT用在代碼視線中。 本質(zhì)的區(qū)別的在于,Q_SIGNALS 與 Q_SLOTS將被moc識別,是必須使用的。而Q_EMIT或者emit是可有可無的。它不會被moc識別,它存在的唯一理由是:增加代碼的可讀性。  也就是說如下代碼都能正常工作,但2)的寫法也許會惹怒你的同事。

             

            1. void method()  
            2. {  
            3.       1) emit signalA();  
            4.       2) signalA();    
            5. }  
             

             

            Q_INVOKABLE

            #define Q_INVOKABLE

             

            使用Q_INVOKABLE來修飾成員函數(shù),目的在于被修飾的成員函數(shù)能夠被元對象系統(tǒng)所喚起。這一機制在Qt C++/QML混合編程,Qt service framework, 以及Qt/ HTML5混合編里廣泛使用。我會隨后另撰寫一文做深入探討。

             

             

            Q_PROPERTY

             

            #define Q_PROPERTY(text)   

             

            使用Q_PROPERTY用以聲明屬性,屬性類似于成員變量,但它能夠被元對象系統(tǒng)所訪問。QML的屬性便是利用該機制得以實現(xiàn)的。 Q_PROPERTY的用法如下:

             

            Q_PROPERTY(QString title READ title WRITE setTitle USER true)

             


             

            接下來,讓我們結(jié)合代碼來看一下上述宏的使用以及元對象編譯器是如何利用這些宏的。

             

             

            1. #include <QDeclarativeItem >  
            2. class EllipseItem : public QDeclarativeItem   
            3. {   
            4.     Q_OBJECT   
            5.     Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)  
            6. public:   
            7.     EllipseItem(QDeclarativeItem *parent = 0);   
            8.     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,   
            9.                QWidget *widget = 0);  
            10.     const QColor &color() const;   
            11.     void setColor(const QColor &newColor);  
            12.     Q_INVOKABLE QColor randomColor() const;  
            13. public Q_SLOTS:   
            14.     void try1();   
            15.     void try2() {}  
            16. Q_SIGNALS:   
            17.     void colorChanged();   
            18.     void ready();  
            19. private:   
            20.     QColor m_color;   
            21. };  
             

             

             

            以下代碼由元對象編譯器moc根據(jù)上述頭文件自動生成:

             

             

            1. static const uint qt_meta_data_EllipseItem[] = {  
            2. // content:   
            3.        5,       // revision   
            4.        0,       // classname   
            5.        0,    0, // classinfo   
            6.        5,   14, // methods   
            7.        1,   39, // properties   
            8.        0,    0, // enums/sets   
            9.        0,    0, // constructors   
            10.        0,       // flags   
            11.        2,       // signalCount  
            12. // signals: signature, parameters, type, tag, flags   
            13.       13,   12,   12,   12, 0x05,   
            14.       28,   12,   12,   12, 0x05,  
            15. // slots: signature, parameters, type, tag, flags   
            16.       36,   12,   12,   12, 0x0a,   
            17.       43,   12,   12,   12, 0x0a,  
            18. // methods: signature, parameters, type, tag, flags   
            19.       57,   12,   50,   12, 0x02,  
            20. // properties: name, type, flags   
            21.       71,   50, 0x43495103,  
            22. // properties: notify_signal_id   
            23.        0,  
            24.        0        // eod   
            25. };  
            26. static const char qt_meta_stringdata_EllipseItem[] = {   
            27.     "EllipseItem/0/0colorChanged()/0ready()/0"   
            28.     "try1()/0try2()/0QColor/0randomColor()/0"   
            29.     "color/0"   
            30. };  
             

             

             

            從上面代碼實例我們可以看到, QT的元對象編譯器moc會識別聲明在頭文件中的宏Q_SIGNALS,Q_SLOTS, Q_PROPERTY, Q_PROPERTY。并以此做為依據(jù),生成了元對象數(shù)據(jù)表。在這張元對象數(shù)據(jù)表中,我們已可以看到,moc根據(jù)頭文件所聲明的宏定義,識別出:

            • 兩個信號:colorChanged(), ready();      (Q_SIGNALS)
            • 兩個槽:    try1(), try2()                          (Q_SLOTS)
            • 五個方法,其中被標(biāo)記為Q_INVOKABLE的方法randomColor()被記錄在元對象字符串?dāng)?shù)組qt_meta_stringdata_EllipseItem中。  
            • 一個屬性:color   (Q_PROPERTY)
            一本色道久久88精品综合| 久久露脸国产精品| 久久久一本精品99久久精品66| 欧美亚洲国产精品久久| 久久久久av无码免费网| 久久国产精品二国产精品| 国产精品一区二区久久精品涩爱 | 97热久久免费频精品99| 99久久无码一区人妻a黑| 久久一区二区免费播放| 久久国产精品77777| 亚洲欧美日韩精品久久亚洲区| 久久精品中文无码资源站| 久久亚洲国产欧洲精品一| 久久受www免费人成_看片中文| 999久久久免费精品国产| 99精品久久久久久久婷婷| 久久久WWW成人免费精品| 久久免费的精品国产V∧| 精品国产乱码久久久久久呢| 久久精品夜色噜噜亚洲A∨ | 亚洲AV无码久久精品色欲 | 久久亚洲精品成人AV| 中文字幕精品无码久久久久久3D日动漫 | 久久大香香蕉国产| 亚洲精品乱码久久久久久蜜桃图片 | 伊人久久综合精品无码AV专区| 免费一级做a爰片久久毛片潮 | 久久精品国产男包| 伊人久久一区二区三区无码| 99久久人人爽亚洲精品美女| 久久久久久久尹人综合网亚洲| 久久亚洲精品国产精品| 久久亚洲精品中文字幕| 人妻精品久久久久中文字幕一冢本| 国内精品综合久久久40p| 亚洲国产精品无码久久| 久久久久久国产精品无码超碰| 久久精品青青草原伊人| 亚洲国产另类久久久精品| 日日噜噜夜夜狠狠久久丁香五月|