一、信号槽机制原理
1、如何声明信号槽
Qt头文件中一段的简化版:
class Example: public QObject
{
Q_OBJECT signals:
void customSignal();
void customSignal(int i)
public slots:
void customSlot();
void customSlot(int i);
};
2、宏与MOC源对象
摘录代码:
// qobjectdefs.h
i. …
ii. #define slots
iii. #define signals public
iv. …
v. #define emit
vi. …
为什么需要MOC?
由于c++原生并没有提供内省,而Qt的信号槽和属性列表是基于内省的,通过内省能很方便的列出对象的方法和属性列表,可以说Qt的信号槽是决定类型安全的。
详细信息可参考:解析Qt内省机制 (所谓内省是指面向对象语言的一种在运行期间查询对象信息的能力)
二、信号槽的发展与使用
Qt5之前的写法:
connect(sender, SIGNAL(customSignal(int i)),receiver, SLOT(customSlot(int i)));
缺点:没有编译器检查,因为信号和槽函数被处理成了字符串,编译器不能在编译时检查错误,所有的检查是在运行时完成的。这样可能会出现编译通过槽却没被调用的情况,
只能在控制台中查看错误提示了。
Qt5新写法:
connect(sender, &Sender::customSignal,receiver, &Receiver::customSlot);
与之前语法很像,新的信号槽特性:
- 新的语法
- 编译器检查
- 友好的错误提示
- 自动参数类型转换
- 允许连接任意函数(使用了函数指针,直接调用函数,所以槽不用经过MOC处理。信号还是需要MOC处理即需要在特定区域声明)
- c++lambda表达式(可以任性的写成如下格式)
connect(this, &Example::customSignal,[=](int i){
cout << "Resule: " << i;
}
常用信号槽用法:
• QtDesigner创建
• void Example::on_pushButton_clicked(){...}
• connect(sender, SIGNAL(customSignal(int i)),
receiver, SLOT(customSlot(int i)));
• connect(sender, &Sender::customSignal,
receiver, &Receiver::customSlot);
• connect(sender, &Sender::customSignal,custonSlot);
• connect(this, &Example::customSignal,[=](int i){
cout << "Resule: " << i;
}
三、Qt组件与信号连接
简单的加法器:
ui界面设计为
右击pushbutton选择转到槽选择clicked方法,会在summator里自动生成并编辑代码,运行
可参考其他文章:QT的信号与槽机制介绍