Qt信号和槽的个人总结

时间:2021-02-02 00:05:45

1、connect

  1. connect(sender,SIGNAL(signal()),receiver,SLOT(slot()));

这里用到了两个宏:SIGNAL() 和SLOT();通过connect声明可以知道这两个宏最后倒是得到一个const char*类型。
在qobjectdefs.h中可以看到SIGNAL() 和SLOT()的宏定义:

  1. #ifndef QT_NO_DEBUG
  2. # define QLOCATION "\0"__FILE__":"QTOSTRING(__LINE__)
  3. # define METHOD(a)   qFlagLocation("0"#a QLOCATION)
  4. # define SLOT(a)     qFlagLocation("1"#a QLOCATION)
  5. # define SIGNAL(a)   qFlagLocation("2"#a QLOCATION)
  6. #else
  7. # define METHOD(a)   "0"#a
  8. # define SLOT(a)     "1"#a
  9. # define SIGNAL(a)   "2"#a
  10. #endif

所以这两个宏的作用就是把函数名转换为字符串并且在前面加上标识符。

比如:SIGNAL(read())展开后就是"2read()";同理SLOT(read())展开后就是"1read()"。

  1. connect(sender,SIGNAL(signal()),receiver,SLOT(slot()));
  2. 实际上就是connect(sender,“2signal()”,receiver,“1slot())”;

2、slots,signals

Qt4源码定义的宏如下:

# define slots

#define signals protected

# define emit

再来看例子:

#ifndef COUNTER_H

#define COUNTER_H

#include <QObject>

class Counter : public QObject
{
    Q_OBJECT

public:
    Counter();

private:
    int m_value1;
    int m_value2;

public slots:
    void setValue1(int value);
    void setValue2(int value);

signals:
    void valueChanged1(int newValue);
    void valueChanged2(int newValue);
};

#endif // COUNTER_H
 
注意,头文件定义的public slots和signals对C++编译器而言没有意义,会被替换成public和protected。他们的真实意图其实是给moc工具使用的,moc根据这些字符串关键字匹配,用来生成文件moc_Counter.cpp。Qt源码的构建过程是先moc转换然后再执行C++编译器。moc的目的是展开信号和槽,生成一个能让编译器读懂的源文件。
以下是生成的moc文件:

QT_BEGIN_MOC_NAMESPACE static const uint qt_meta_data_Counter[] = {

// content:        6,       // revision //指明moc生成代码的版本号:Qt4的moc生成的代码,该值是6,也就是相当于moc v6;Qt5则是7        0,       // classname //类名的索引,在数组qt_meta_stringdata_Counter的起始下标是0        0,    0, // classinfo        4,   14, // methods //有4个函数(2个信号函数,2个槽函数);函数的描述在数组qt_meta_data_Counter的起始下标是14        0,    0, // properties        0,    0, // enums/sets        0,    0, // constructors        0,       // flags        2,       // signalCount //信号函数的数量

// signals: signature, parameters, type, tag, flags       18,    9,    8,    8, 0x05, //信号的索引,在数组qt_meta_stringdata_Counter的起始下标是18,flags:0x05表示是信号       37,    9,    8,    8, 0x05, //同上

// slots: signature, parameters, type, tag, flags       62,   56,    8,    8, 0x0a, //槽的索引,在数组qt_meta_stringdata_Counter的起始下标是62,flags:0x0a表示是槽

77,   56,    8,    8, 0x0a, //同上

0        // eod };

static const char qt_meta_stringdata_Counter[] = {     "Counter\0\0newValue\0valueChanged1(int)\0"     "valueChanged2(int)\0value\0setValue1(int)\0"     "setValue2(int)\0" };

文章来源:

http://blog.csdn.net/oowgsoo/article/details/1529411 Qt源码分析之信号和槽机制

http://www.devbean.net/2012/12/how-qt-signals-and-slots-work/ Qt信号槽的实现

http://woboq.com/blog/how-qt-signals-slots-work.html How Qt Signals and Slots Work

http://mobile.51cto.com/symbian-270982_all.htm 详解QT源码之QT元对象系统和信号槽机制

http://mobile.51cto.com/symbian-288016.htm 解析关于Qt Quick宏学习教程
http://blog.csdn.net/superfpe/article/details/5782707 Qt的Signal和Slot机制(一)★

http://blog.csdn.net/superfpe/article/details/5788636 Qt的Signal和Slot机制(二)★

http://blog.csdn.net/ybjx111/article/details/8272405 QT QObject::connect函数的学习★

http://blog.csdn.net/libaineu2004/article/details/19476039