• <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 閱讀(827) 評(píng)論(0)  編輯 收藏 引用 所屬分類: QtQML

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

             

            剛開始接觸Qt的朋友可能對(duì)Qt在使用當(dāng)中需要聲明的各色各樣的宏感到神秘而又陌生,本文將介紹Qt中經(jīng)常使用的幾個(gè)宏: 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所有宏中最為重要的一個(gè),Q_OBJECT是使用信號(hào)槽機(jī)制以及其他所有元對(duì)象系統(tǒng)提供的服務(wù)(內(nèi)省、invokeMethod,元對(duì)象property系統(tǒng)等等)的前提條件。有關(guān)Q_OBJECT的討論請(qǐng)參考Qt源碼分析之QObject。 

            SIGNAL與SLOT

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

             

            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. }  
             

             

            原來它會(huì)基于把我們定義的信號(hào)、槽的名稱返回一個(gè)字符串,比如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,原因是更好的與第三方信號(hào)槽機(jī)制兼容,比如boost庫。盡管Q_SIGNALS 與 Q_SLOTS看起來沒有做什么。其實(shí)不然,QT的元對(duì)象編譯器moc會(huì)識(shí)別聲明在頭文件中的宏Q_SIGNALS,Q_SLOTS。并做為依據(jù),生成元對(duì)象模型數(shù)據(jù),詳見文中最后所示代碼實(shí)例

            Q_EMIT

            #define Q_EMIT #define emit

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

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

             

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

             

            Q_INVOKABLE

            #define Q_INVOKABLE

             

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

             

             

            Q_PROPERTY

             

            #define Q_PROPERTY(text)   

             

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

             

            Q_PROPERTY(QString title READ title WRITE setTitle USER true)

             


             

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

             

             

            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. };  
             

             

             

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

             

             

            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. };  
             

             

             

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

            • 兩個(gè)信號(hào):colorChanged(), ready();      (Q_SIGNALS)
            • 兩個(gè)槽:    try1(), try2()                          (Q_SLOTS)
            • 五個(gè)方法,其中被標(biāo)記為Q_INVOKABLE的方法randomColor()被記錄在元對(duì)象字符串?dāng)?shù)組qt_meta_stringdata_EllipseItem中。  
            • 一個(gè)屬性:color   (Q_PROPERTY)
            伊人久久一区二区三区无码| 久久久女人与动物群交毛片 | 国产成人久久精品一区二区三区| 久久久久久国产a免费观看黄色大片 | 理论片午午伦夜理片久久| 亚洲精品乱码久久久久久按摩 | 人妻丰满?V无码久久不卡| 久久狠狠高潮亚洲精品| 亚洲国产高清精品线久久| 成人妇女免费播放久久久| 亚洲人成无码www久久久| 狠狠狠色丁香婷婷综合久久俺| 日韩美女18网站久久精品| 国产精品久久久久天天影视| 亚洲精品乱码久久久久久蜜桃 | 久久精品人人做人人爽97| 色婷婷久久久SWAG精品| 热99re久久国超精品首页| 亚洲国产一成人久久精品| 怡红院日本一道日本久久 | 久久精品国产久精国产一老狼| 99久久精品国产高清一区二区 | 久久香蕉国产线看观看99| 亚洲色婷婷综合久久| 久久青青草视频| 无码人妻少妇久久中文字幕 | 狠狠人妻久久久久久综合| 九九99精品久久久久久| 久久AV高清无码| 久久久久久久97| 97香蕉久久夜色精品国产 | 一本色综合网久久| 97香蕉久久夜色精品国产| 色综合久久久久综合99| 久久久久国色AV免费看图片| 国产精品99久久不卡| 久久久久久国产a免费观看不卡| 亚洲国产天堂久久综合网站| 91精品免费久久久久久久久| 色综合色天天久久婷婷基地| 国产精品免费看久久久香蕉|