• <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++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            Qt/Qt Quick宏淺議

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

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

             

            剛開始接觸Qt的朋友可能對Qt在使用當中需要聲明的各色各樣的宏感到神秘而又陌生,本文將介紹Qt中經常使用的幾個宏: 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是使用信號槽機制以及其他所有元對象系統提供的服務(內省、invokeMethod,元對象property系統等等)的前提條件。有關Q_OBJECT的討論請參考Qt源碼分析之QObject。 

            SIGNAL與SLOT

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

            Q_EMIT

            #define Q_EMIT #define emit

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

            這里要注意,我們看到Q_EMIT看起來同樣的簡單, 但它們是有區別的!表面的區別在于Q_SIGNALS 與 Q_SLOTS用在頭文件中,而Q_EMIT用在代碼視線中。 本質的區別的在于,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來修飾成員函數,目的在于被修飾的成員函數能夠被元對象系統所喚起。這一機制在Qt C++/QML混合編程,Qt service framework, 以及Qt/ HTML5混合編里廣泛使用。我會隨后另撰寫一文做深入探討。

             

             

            Q_PROPERTY

             

            #define Q_PROPERTY(text)   

             

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

             

            Q_PROPERTY(QString title READ title WRITE setTitle USER true)

             


             

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

             

             

            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根據上述頭文件自動生成:

             

             

            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。并以此做為依據,生成了元對象數據表。在這張元對象數據表中,我們已可以看到,moc根據頭文件所聲明的宏定義,識別出:

            • 兩個信號:colorChanged(), ready();      (Q_SIGNALS)
            • 兩個槽:    try1(), try2()                          (Q_SLOTS)
            • 五個方法,其中被標記為Q_INVOKABLE的方法randomColor()被記錄在元對象字符串數組qt_meta_stringdata_EllipseItem中。  
            • 一個屬性:color   (Q_PROPERTY)
            久久精品日日躁夜夜躁欧美| 天天影视色香欲综合久久| 国产AⅤ精品一区二区三区久久| 久久婷婷五月综合色奶水99啪| 日本精品久久久久中文字幕8 | 日本三级久久网| 久久夜色精品国产噜噜亚洲AV| 久久播电影网| 久久久这里有精品中文字幕| 一本一道久久精品综合| 韩国无遮挡三级久久| 精品免费tv久久久久久久| 久久成人国产精品| 国产精品久久久久久吹潮| 婷婷伊人久久大香线蕉AV| 久久久久人妻一区精品性色av| 亚洲va国产va天堂va久久| 亚洲国产精品无码久久九九| 久久精品综合一区二区三区| 99精品国产在热久久无毒不卡| 美女写真久久影院| 麻豆久久久9性大片| 老司机国内精品久久久久| 亚洲va久久久久| 久久亚洲国产成人精品无码区| 亚洲国产综合久久天堂 | 久久久久久久波多野结衣高潮| 久久久久亚洲?V成人无码| 伊人久久大香线蕉成人| 亚洲AV乱码久久精品蜜桃| 久久久久久人妻无码| 中文字幕亚洲综合久久2| 国产精品丝袜久久久久久不卡 | 97久久精品人人做人人爽| 中文字幕久久精品无码| 久久国产精品-国产精品| 久久天天躁狠狠躁夜夜2020老熟妇 | 久久中文字幕一区二区| 久久精品国产91久久麻豆自制| 久久无码精品一区二区三区| 色偷偷88888欧美精品久久久|