SIGNAL AND SLOTS,是Qt的核心机制,Qt和其他传统的GUI工具包不一样,不是采用CALLBACK响应触发动作.
SIGNAL: 当对象本身发生了一些令对象的client和ower感兴趣的改变,那么信号就会被发射.只有定义过这个信号
的类或者是其派生类才可以发射信号.当信号发射后,与其相关联的槽将被执行,就像是函数调用一样.信号槽机制独
立与任何GUI事件循环,当所有的槽都返回的时候,就会返回发射清单.当使用queued connections稍微有些不同.
如果多个槽与一个信号相连,当信号被发射后,槽将会按照槽连接的顺序一个接着一个的执行.(这里是Qt4.8 Reference
Document上面的文档,但是看过很多的旧版资料都是说明槽在执行的时候顺序是不确定的,而且我们是无法指定的,
看起来新版不同.)
信号由moc生成,而且不能在.cpp源文件中实现,它们不能有返回类型.(只能是void)
SLOTS: 槽是普通的C++函数,而且可以被正常调用.唯一特殊的地方就是它们可以与信号关联,当信号被发射的时候,
槽就被执行.
下面有一段话,我觉得自己可能会翻译的不好,所以贴出来.
Since slots are normal member functions, they follow the normal C++ rules when called directly. However,
as slots, they can be invoked by any component, regardless of its access level, via a signal-slot
connection. This means that a signal emitted from an instance of an arbitrary class can cause a private
slot to be invoked in an instance of an unrelated class.
槽也是普通的成员函数,也遵从正常的C++访问规则. 然而,忽略权限限制,只要通过信号-槽连接,槽就可以被任意组件
调用.上面一句话的意思就是,任意对象发射信号都可以导致一个无关的类去调用私有槽.
其实呢,我觉得上面这句话的意思就是槽和普通的C++成员函数一样,都是有访问权限的.
信号与槽的连接:
Assistant中很容易找得到OBject::connect函数:
下面看看disconnect函数:
1. 一个信号可以连接多个槽
2. 多个信号可以连接一个槽
3. 一个信号可以与另外一个信号相连
4. 连接可以被移除
5. 要把信号成功连接到槽,(或者连接到另一个信号),它们的参数必须具有相同的顺序和相同的类型.
6. 如果信号的参数比它所连接的槽的参数多,多余的参数将会被简单的忽略掉.
另外需要注意的一点是: 在指定信号的时候必须使用宏SIGNAL(),在指定槽函数的时候必须使用宏SLOT().
如果发射者和接受者属于同一个对象的话,那么connect调用中接受者参数可以省略.
需要注意的一些问题:
1. 信号与槽的效率是很高的,但是同真正的回调函数比起来,由于增加了弹性,所以在速度上面稍微有点慢.
2. 信号与槽机制同普通的函数一样,如果使用不当的话,也是会产生死循环的.因此,在定义槽函数的时候一定
要注意避免形成无限循环,即在槽中再次发射所接受到的信号.
3. 如果一个信号与多个槽想关联的话,那么,当这个信号被发射时,与之相关联的槽的顺序是随机的,而且我们
不能指定该顺序(....这个问题在前面说过了,由于文档的原因,值得商榷,后面找到确切解答再完善.)
4. 宏定义不能用在signal和slot参数中.
5. 构造函数不能在signals和slots声明区域内.
6. 函数指针不能作为信号或槽的参数.(为了避免产生歧义,可以通过其他办法绕过,使用typedef)
7. 信号与槽不能有缺省参数.
8. 信号与槽不能携带模板类参数(解决的办法同上,也可以使用typedef解决)
2102.8.17 9:30AM