简述
在GUI编程中,当我们改变一个控件的时候,我们常常需要通知另一个控件这种变化。更通俗地说,我们希望任何对象之间都能够互相通信。
其它的开发套件会采用回调函数(callbacks)来实现对象之间的通信。采用这种回调函数的成功框架的确存在,但是回调函数还是不够直观而且存在参数正确性的问题。
信号槽(signals and slots)用来实现Qt对象之间的通信,它是Qt的核心功能,而且可能是Qt与其他框架最大的不同点。
使用
我们通过一个按钮关闭窗口
示例来展示信号槽的基本使用方法
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
QPushButton * btn1 = new QPushButton;
connect(btn1, &QPushButton::clicked, this, &QWidget::close);
}
效果

connect(sender, signal, receiver, slot)四个参数的意义:
参数 | 意义 |
---|---|
sender | 发出信号的对象,一般是一个对象指针 |
signal | 发送对象发出的信号,一般是一个成员函数指针 |
receiver | 接收信号的对象,一般是一个对象指针 |
slot | 处理信号的函数,一般是一个成员函数指针 |
自定义带参信号槽
endTest作为槽函数,startTest作为信号函数,start作为触发函数(用来触发信号函数):
public:
Widget(QWidget *parent = 0);
~Widget();
void start();
Public slots:
void endTest(QString y);
signals:
void startTest(QString x);
下面是endtest和start的具体实现:
void Widget::endTest(QString y)
{
qDebug() << "End test" << y.toUtf8().data();
}
void Widget::start()
{
emit startTest("000");
}
下面是构造函数中的connect函数调用和start函数触发:
connect(this, &Widget::startTest, this, &Widget::endTest);
start();
最终endTest会根据startTest带的参数来发出对应的字符串。
几点说明:
- 信号函数的参数要大于等于槽函数的参数,而且前几个要类型一致。
- siginals标记的信号函数只需声明不用实现。
- 任何成员函数、static 函数、全局函数和 Lambda 表达式都可以作为槽函数。
- 一个信号可以多个槽,一个槽也可以多个信号,一个信号可以连接到另一个信号,可以取消连接(disconnect)。