目录
信号和槽介绍
信号与插槽机制,提供对象间的通信机制。可以取代原始的回调和消息映射机制。信号与槽是迅速的,类型安全的,健壮的,完全面向对象并用C++实现的一种机制。
回调机制
- 不能确认回调执行时候传递进来的函数参数是否是正确的类型,容易造成进程崩溃。
- 回调这种方式紧紧绑定了图形用户接口的功能元素,很难吧开发进行独立的分类。
信号槽机制
- 信号与槽机制是类型安全的,它以警告的方式报告类型错误,而不会使系统产生崩溃。
- 信号和槽通过使用connect()函数建立连接,不要求类之间想回知道细节,可以方便开发出代码高可用的类。
信号
当对象内部状态发生改变,然后发射信号。
只有定义了一个信号的类和他的子类才能发射这个信号。信号可以重载。
槽
-
当一个和槽连接的信号被发射时候,这个槽被调用。
-
槽和普通函数一样,特点是可以被信号连接。槽的参数不能含有默认值。
-
槽函数可以定义为虚函数,子类通过重写也是非常有用的。
-
槽函数和普通函数一样具有访问权限。
Pubic slots:任何信号都可以连接。
Protected slots:这个类和它的子类可以连接。
Private slots:这个类本身的信号可以连接。
信号槽和直接调用效率问题
信号和槽对比回调稍微有些慢,但是其灵活性的优势,在开发中速度可以被忽略。通常发射一个和槽相连接的信号,大约只比直接调用那些非虚函数的接收器慢十倍。这是定位连接对象造成的开销。
十个非虚函数调用时间开销大概比“new”和“delete”操作少一些。在一台i585-500机器上,每秒钟大概发送2 000 000个左右信号到一个接收器上,或者发送1 200 000到两个接收器上。
信号和槽的使用对比
连接信号和槽函数connect(sender, signal, receiver, slot);
sender:发出信号的对象
signal:发送对象发出的信号
receiver:接收信号的对象
slot:接收对象在接收到信号之后所需要调用的函数
QPushButton button("Quit");
QT5 写法
QObject::connect(&button, &QPushButton::clicked,&app, &QApplication::quit);
编译期间检查类型是否匹配。Qt 5 中,任何成员函数、static 函数、全局函数和 Lambda 表达式都可以作为槽函数。
QT4 写法
QObject::connect(&button, SIGNAL(clicked()), &app, SLOT(quit()));
SIGNAL和SLOT这两个宏,将两个函数名转换成了字符串,编译期间检查不出错误,出现问题在运行期间表现。可能造成程序不稳定。
写到这里发现网上有一个图片,内容总结的挺好。分享给大家。
(图片来源于:https://www.cnblogs.com/wanghui1234/p/8964968.html)
总结
信号和槽的使用必须包含Q_OBJECT宏在使用信号和槽的类中,在MOC元编译器编译源文件时候遇到该宏辉自动生成另一个包含有元对象的C++代码。在使用信号和槽是,其特殊性,要注意一下问题。
- Signal,slot 可以接受参数,但是不能接受函数的指针
- 不支持缺省的参数
- 所有的signal和slot不能有返回值(必须是void)
- Slot可以是虚函数
- Signal的访问权限和protected相同,只有本身和其派生类可以emit signal
- Signal和slot不能是构造函数