Signals and Slots in Depth
信号和槽机制是Qt编程的基础。它使应用程序员能够在对象之间互相不知道任何联系的情况下把这些对象帮定在一起。我们已经连接了一些信号和槽,声明了我们自己的信号和槽,执行自己的槽,发出自己的信号。让我们花点时间深入点看这个机制。
槽与普通的C++成员函数几乎一样。它们可以是virtual,overloaded,public,protected,private,并且可以被其他C++成语函数直接调用。区别是槽可以被信号连接,信号被发送将它自动调用。
connect()声明如下:
connect(sender, SIGNAL(signal), receiver, SLOT(slot));
sender和receiver是指向QObjects的指针,signal和slot是没有参数名的函数signatures(签名)。SIGNAL()和SLOT()宏将转换它们的参数成为一个字符串。
刚才的例子中我们总是连接不同的信号到不同槽,有更多的可能去探究:
1 . 一个信号可以连接很多槽:
connect(slider, SIGNAL(valueChanged(int)),spinBox, SLOT(setValue(int)));
connect(slider, SIGNAL(valueChanged(int)),this, SLOT(updateStatusBarIndicator(int)));
当信号发出,这些槽一个接一个被调用,以任意顺序。
2 . 很多信号可以连接到同样的槽:
connect(lcd, SIGNAL(overflow()),this, SLOT(handleMathError()));
connect(calculator, SIGNAL(divisionByZero()),this, SLOT(handleMathError()));
其中任何一个信号发出时,这个槽被调用。
3. 一个信号可以连接到另一个信号:
connect(lineEdit, SIGNAL(textChanged(const QString &)),this, SIGNAL(updateRecord(const QString &)));
当第一个信号发出,第二个信号也会发出.从这点,singnal-singnal连接与signal-slot连接不能区分.
4 . 连接可以被移除:
disconnect(lcd, SIGNAL(overflow()),this, SLOT(handleMathError()));
这个很少需要,因为Qt在对象删除的时候自动删除所有包括对象的连接.
当连接一个信号到一个槽(或者连接到另一个信号),它们都必须用同样的顺序有同样的参数:
connect(ftp, SIGNAL(rawCommandReply(int, const QString &)),this, SLOT(processReply(int, const QString &)));
异常情况,如果信号比它连接的槽更多的参数,增加的参数将直接忽略:
connect(ftp, SIGNAL(rawCommandReply(int, const QString &)),this, SLOT(checkErrorCode(int)));
如果参数类型不符合,或者信号或槽不存在,Qt将输出一个运行时警告.同样,如果参数名被包含在信号或槽signatures(签名)里,Qt将给一个警告.