1. 概念
**信号(Signal)**就是在特定情况下被发射的事件,如点击按钮会发送 click()事件。
**槽(Slot)**就是对信号响应的函数。槽就是一个函数,与一般的 C++函数是一样的,可以
定义在类的任何部分(public、private 或 protected),可以具有任何参数,也可以被直接调用。槽函数与一般的函数不同的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。
2. 使用
信号与槽使用 QObject::connect() 函数进行关联:
QObject::connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));
其中,sender 是发射信号的对象的名称,signal() 是信号名称。信号可以看做是特殊的函
数,需要带括号,有参数时还需要指明参数。receiver 是接收信号的对象名称,slot() 是槽函数的名称,需要带括号,有参数时还需要指明参数。
断开信号关联使用 disconnect()。
bool QObject::disconnect(const QObject *sender, const char *signal, const QObject *receiver, constchar *method)
如:
断开一切与 myObject 连接的信号或槽。
disconnect(myObject, 0, 0, 0);
相当于非静态重载函数:
myObject->disconnect();
断开所有连接到特定信号的东西。
disconnect(myObject, SIGNAL(mySignal()), 0, 0);
相当于非静态重载函数:
myObject->disconnect(SIGNAL(mySignal()));
与指定的接收者断开连接。
disconnect(myObject, 0, myReceiver, 0);
相当于非静态重载函数:
myObject->disconnect(myReceiver);
3. 注意事项
connect(pushButton, SIGNAL(clicked()), this, SLOT(hide());
connect(pushButton, SIGNAL(clicked()), this, SLOT(close());
当一个信号与多个槽函数关联时,槽函数按照建立连接时的顺序依次执行
- 当信号和槽函数带有参数时,在 connect()函数里,要写明参数的类型,但可以不写参数名称。
- 多个信号可以连接同一个槽。
connect(pushButton,SIGNAL(clicked()),this,SLOT(close()));
connect(pushButton_2,SIGNAL(clicked()),this,SLOT(close()));
connect(pushButton_3,SIGNAL(clicked()),this,SLOT(close()));
connect(pushButton,SIGNAL(objectNameChanged(QString)),this,SIGNAL(windowTitelChanged(QString)));
严格的情况下,信号与槽的参数个数和类型需要一致,至少信号的参数不能少于槽的参数。如果不匹配,会出现编译错误或运行错误。
- 在使用信号与槽的类中,必须在类的定义中加入宏 Q_OBJECT(特别重要)。
- 信号只需声明,无需定义。
- 槽可以是任何成员函数、普通全局函数、静态函数。
- 槽函数和信号的参数和返回值要一致。
4. 测试例程
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPushButton>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
signals:
/* 声明一个信号,只需声明,无需定义 */
void pushButtonTextChanged();
public slots:
/* 声明一个槽函数 */
void changeButtonText();
/* 声明按钮点击的槽函数 */
void pushButtonClicked();
private:
QPushButton *pushButton;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
this->resize(800,480);
pushButton = new QPushButton(this);
pushButton->setText("我是一个按钮");
connect(pushButton,SIGNAL(clicked()),this,SLOT(pushButtonClicked()));
connect(this,SIGNAL(pushButtonTextChanged()),this,SLOT(changeButtonText()));
}
MainWindow::~MainWindow()
{
}
/* 实现按钮点击槽函数 */
void MainWindow::pushButtonClicked()
{
emit pushButtonTextChanged();
}
/* 实现按钮文本改变的槽函数 */
void MainWindow::changeButtonText()
{
/* 在槽函数里改变按钮的文本 */
pushButton->setText(" 被点击了!");
}
运行效果: