在上周老师说了项目须要学习qt后,就去找了个qt的教程,看了看,教程一上来就开始介绍qt的信号与槽,说这是qt中一个很重要的东西,而后就下一步了……,后面的代码中也没有特别感觉到这个的强大与独特(应该是对编程的理解还不够深的缘由),就上网找了找技术博客看,发现大部分文章都对菜鸟不太友好,不过最终仍是让我找到了一篇让新手也能透彻明白的文章 ,这里记录一下本身的收获。编程
先让咱们看看它的定义:安全
听着很强,很高级。框架
简单的用途就是函数
当一个特定的事件发生时,一个或几个被指定的信号就被发射,槽就是一个返回值为void的函数,若是存在一个或几个槽和该信号相链接,那在该信号被发射后,这个(些)槽(函数)就会马上被执行
理解却是不难,不就是触发了一个函数吗?彻底感觉不到做为一个框架的核心特性的强大。学习
要感觉它的强大仍是得从它的做用中体会(也许教程中的老师也是这么想的,只是我没体会到……)。spa
在图形界面编程中,不少时候咱们但愿一个可视对象发生某种变化时通知另外一个或几个对象,再一个地说,咱们但愿任 何一类的对象能和其余对象进行通信。例如,某个数值显示窗口负责显示某个滚动条对象的当前数值,当滚动条对象的值发生变化时,咱们但愿数值显示窗口能收到 来自滚动条对象发送的“数值改变”的信号,从而改变本身的显示数值。.net
这些在其余图形框架中能够用回调实现,不过,相比于回调函数,信号和槽机制是类型安全的(没搞太懂为何安全),一个信号的签名必须与它的接收槽的签名相匹配,这样编译器就能够帮助咱们检查类型是否匹配。信号和槽是很宽松的联系在一 起的,一个发射信号的对象不用考虑哪一个槽会接收这个信号,接收信号的槽的所在对象也不知道要链接的信号是哪一个对象发射的。QT的信号和槽机制能够保证若是 你把一个信号和一个槽链接起来后,槽会在正确的时间使用信号的参数而被调用,信号和槽可使用任何数量、类型的参数。
换一种说法,在使用信号与槽时你得先链接一下他们。下面是信号与槽的代码实现指针
使用信号和槽的QT对象: class UseSignalClass { Q_OBJECT public: UseSignalClass (void) {} int value (void) const {return _value;} public slots: int setValue (int value) {_value = value;} // 定义槽 signals: void valueChanged (int); private: int _value; } void UseSignalClass::setValue( int value ) { if ( value != _value ) { _val = value; emit valueChanged(value); } } emit valueChanged(value);这行代码是发射一个信号valueChanged。 要想使一个槽在一个信号被发射后被执行,要显示地进行链接: UseSignalClass a,b; connect(&a, SIGNAL(valueChanged(int)), &b, SLOT(setValue(int)));
而后当a改变时,b也会跟着变,而b的改变不会影响到a,由于b不会给a发信号。code
下面是信号与槽的使用中的一些注意事项:对象
一、信号和槽的机制是很是有效的,可是它不像“真正的”回调那样快。信号和槽稍微有些慢,这是由于它们所提供的灵活性。但这种损失相对来讲是比较小的。但要追求高效率的话,好比在实时系统中就要尽可能少用这种机制。
二、信号和槽机制与普通函数的调用同样,若是使用不当的话,在程序执行时有可能造成死循环,因此,在定义槽函数时必定要注意避免间接造成无限循环,即在槽中再次发射所接收到的一样的信号。
三、若是一个信号和多个槽相关联的话,那当这个信号被发射时,与之相关联的槽的执行顺序将是髓机的,且顺序不能指定。
四、宏定义不能用在signal和slot的参数中。
五、构造函数不能用在signals和slots声明区域内。
六、函数指针不能做为信号或槽的参数。
七、信号和槽不能有缺省参数值。
八、信号和槽不能携带模板类参数。
九、嵌套的类不能位于信号和槽区域内,也不能有信号或者槽。
十、友元声明不能位于信号和槽的声明区域内。
学习是一个一步一步的过程,学的时候千万不要太着急,应该克制本身总想直接搞最后一步的想法,毕竟那样学习曲线会太过陡峭,容易让人失去信心,就像此次要不是知道回调,在看相关博客时,确定也是看的云里雾里的。