Qt中信号和槽的关联使用的是QObject类的connect()函数,该函数的原型如下:
[static] QMetaObject::Connection QObject::connect(const QObject * sender,
const char * signal,
const QObject * receiver,
const char * method,
Qt::ConnectionType type = Qt::AutoConnection)
第一个参数为发射信号的对象;
第二个参数是要发射的信号;
第三个参数是接收信号的对象;
第四个参数是要执行的槽函数,该参数也可以指定一个信号,实现信号与信号的关联。
在Qt4中对于信号和槽,必须使用SIGNAL()和SLOT()宏,它们可以将其参数转化为const char * 类型,另外,第四个参数指定的槽在声明时必须使用slots关键字。connect()函数的返回值为QMetaObject::Connection类型。在Qt4写法中调用connect()函数时信号与槽的参数只能有类型,不能有变量名,例如写成SLOT(send(QString str))是不对的。
connect()函数的最后一个参数type表明了关联的方式,由Qt::ConnectionType枚举类型指定,其类型如下表所示,默认值是Qt::AutoConnection。
信号与槽关联类型表
关联类型 | 描述 |
Qt::AutoConnection | 自动关联,默认值。如果receiver存在于发射信号的线程,则使用Qt::DirectConnection;否则,使用Qt::QueuedConnection。在信号被发射时决定使用哪种关联类型。 |
Qt::DirectConnection | 直接关联。发射完信号后立即调用槽,只有槽执行完成返回后,发射信号处后面的代码才可以执行。 |
Qt::QueuedConnection | 队列关联。当控制返回receiver所在线程的事件循环后再执行槽,无论槽执行与否,发射信号处后面的代码都会立即执行。 |
Qt::BlockingQueuedConnection | 阻塞队列关联。类似Qt::QueuedConnection,不过,信号线程会一直阻塞,直到槽返回。当receiver存在于信号线程时不能使用该类型,不然程序会死锁。 |
Qt::UniqueConnection | 唯一关联。这是一个标志,可以结合其他几种连接类型,使用按位或操作。这时两个对象间的相同的信号和槽只能有唯一的关联。使用这个标志主要为了防止重复关联。 |
重点:一般在类或者函数中使用emit发射了信号之后,就会立即执行响应的槽函数,只有等槽函数执行完了以后才会继续接着执行emit语句后面的代码。
connect()函数另外一种常用的基于函数指针的重载形式如下:
[static]QMetaObject::Connection QObject::connect(const QObject *sender,
PointerToMemberFunction signal,
const QObject *receiver,
PointerToMemberFunction method,
Qt::ConnectionType type = Qt::AutoConnection)
这是Qt5中加入的一种重载形式,与前者最大的不同就是,指定信号和槽两个参数时不再使用SIGNAL()和SLOT()宏,并且槽函数不再必须是使用slots关键字声明的函数,而可以是任意能和信号关联的成员函数。
使用这种方式与前一种相比,还有一个好处就是可以在编译时进行检查,信号或槽的拼写错误、槽函数参数数目多于信号的参数数目等错误在编译时就能够被发现。这种方式还可以使用C++中的Lambda表达式,可以直接在关联时编写要执行的代码。