深度解析 Qt Quick 宏
创始人
2024-08-02 08:21:43
0

Qt Quick 宏是本篇所介绍的内容。刚开始接触Qt的朋友可能对Qt在使用当中需要声明的各色各样的感到神秘而又陌生,本文将介绍Qt中经常使用的几个: Q_OBJECT, SIGNAL与SLOT, Q_SIGNALS 与 Q_SLOTS, Q_EMIT ,Q_INVOKABLE, Q_PROPERTY:

的头文件出处: $QTDIR\src\corelib\kernel\qobjectdefs.h

  1. Q_OBJECT  
  2. #define Q_OBJECT \   
  3. public: \   
  4.     Q_OBJECT_CHECK \   
  5.     static const QMetaObject staticMetaObject; \   
  6.     Q_OBJECT_GETSTATICMETAOBJECT \   
  7.     virtual const QMetaObject *metaObject() const; \   
  8.     virtual void *qt_metacast(const char *); \   
  9.     QT_TR_FUNCTIONS \   
  10.     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()));    
  3. QObject::connect(myButton, SIGNAL(clicked()),   
  4.                   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. }    
  12. $QTDIR\src\corelib\kernel\qobjectdefs.h  
  13. # define SLOT(a)     qFlagLocation("1"#a QLOCATION)   
  14. # define SIGNAL(a)   qFlagLocation("2"#a QLOCATION)  
  15. $QTDIR\src\corelib\kernel\qobject.cpp  
  16. const char *qFlagLocation(const char *method)   
  17. {   
  18.     static int idx = 0;   
  19.     flagged_locations[idx] = method;   
  20.     idx = (idx+1) % flagged_locations_count;   
  21.     return method;   
  22. }  

原来它会基于把我们定义的信号、槽的名称返回一个字符串,比如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    
  6. Q_SIGNALS 与 Q_SLOTS  
  7. #  define slots   
  8. #  define signals protected   
  9. # define Q_SLOTS   
  10. # define Q_SIGNALS protected  

Q_SIGNALS 与 Q_SLOTS是Qt 4.1引入的,它们用来替换关键字signals和slots,原因是更好的与第三方信号槽机制兼容,比如boost库。尽管Q_SIGNALS 与 Q_SLOTS看起来没有做什么。其实不然,QT的元对象编译器moc会识别声明在头文件中的宏Q_SIGNALS,Q_SLOTS。并做为依据,生成元对象模型数据,详见文中***所示代码实例

  1. Q_EMIT  
  2. #define Q_EMIT 

#define emitQ_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. }    
  6. void method()  
  7. {  
  8.       1) emit signalA();  
  9.       2) signalA();    
  10. }   
  11. Q_INVOKABLE  
  12. #define Q_INVOKABLE 

使用Q_INVOKABLE来修饰成员函数,目的在于被修饰的成员函数能够被元对象系统所唤起。这一机制在Qt C++/QML混合编程,Qt service framework, 以及Qt/ HTML5混合编程里广泛使用。我会随后另撰写一文做深入探讨。

  1. Q_PROPERTY  
  2. #define Q_PROPERTY(text)    

使用Q_PROPERTY用以声明属性,属性类似于成员变量,但它能够被元对象系统所访问。QML的属性便是利用该机制得以实现的。 Q_PROPERTY的用法如下:

  1. Q_PROPERTY(QString title READ title WRITE setTitle USER true) 

接下来,让我们结合代码来看一下上述宏的使用以及元对象编译器是如何利用这些宏的。

  1. #include      
  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. };    
  22. #include  
  23. class EllipseItem : public QDeclarativeItem   
  24. {   
  25.     Q_OBJECT   
  26.     Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)  
  27. public:   
  28.     EllipseItem(QDeclarativeItem *parent = 0);   
  29.     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,   
  30.                QWidget *widget = 0);  
  31.     const QColor &color() const;   
  32.     void setColor(const QColor &newColor);  
  33.     Q_INVOKABLE QColor randomColor() const;  
  34. public Q_SLOTS:   
  35.     void try1();   
  36.     void try2() {}  
  37. Q_SIGNALS:   
  38.     void colorChanged();   
  39.     void ready();  
  40. private:   
  41.     QColor m_color;   
  42. }; 

 

以下代码由元对象编译器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. };    
  31. static const uint qt_meta_data_EllipseItem[] = {  
  32. // content:   
  33.        5,       // revision   
  34.        0,       // classname   
  35.        0,    0, // classinfo   
  36.        5,   14, // methods   
  37.        1,   39, // properties   
  38.        0,    0, // enums/sets   
  39.        0,    0, // constructors   
  40.        0,       // flags   
  41.        2,       // signalCount  
  42. // signals: signature, parameters, type, tag, flags   
  43.       13,   12,   12,   12, 0x05,   
  44.       28,   12,   12,   12, 0x05,  
  45. // slots: signature, parameters, type, tag, flags   
  46.       36,   12,   12,   12, 0x0a,   
  47.       43,   12,   12,   12, 0x0a,  
  48. // methods: signature, parameters, type, tag, flags   
  49.       57,   12,   50,   12, 0x02,  
  50. // properties: name, type, flags   
  51.       71,   50, 0x43495103,  
  52. // properties: notify_signal_id   
  53.        0,  
  54.        0        // eod   
  55. };  
  56. static const char qt_meta_stringdata_EllipseItem[] = {   
  57.     "EllipseItem\0\0colorChanged()\0ready()\0"   
  58.     "try1()\0try2()\0QColor\0randomColor()\0"   
  59.     "color\0"   
  60. };  

从上面代码实例我们可以看到, 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)

原始作者地址http://blog.csdn.net/changsheng230

小结:关于深度解析 Qt Quick宏浅议的内容介绍完了,希望本文对你有所帮助!

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
Windows恶意软件20年“... 在Windows的早期年代,病毒游走于系统之间,偶尔删除文件(但被删除的文件几乎都是可恢复的),并弹...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
着眼MAC地址,解救无法享受D... 在安装了DHCP服务器的局域网环境中,每一台工作站在上网之前,都要先从DHCP服务器那里享受到地址动...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...