- 信号(signal) 就是在特定情况下被发射的时间
- 槽(slog) 就是对信号的相应函数。槽就是一个函数,与一般的C++函数一样,可以定义在类的任何部分(public、private、protected),可以具有任何参数,也可以被直接调用
信号与槽的关联使用 QObject::connect() 函数实现的,其基本格式是:
QObject::connect(sender, SIGNAL(signal()), receiver, SLOG(slot()));
connect() 是 QObject类的一个静态函数,而QObject是所有Qt类的基类,在实际调用时可以忽略前面的限定符,直接写为
connect(sender, SIGNAL(signal()), receiver, SLOG(slot()));
关于信号与槽的使用,有以下一些规则需要注意:
- 一个信号可以连接多个槽,槽函数按照建立连接时的顺序一次执行。当信号与槽函数带有参数时,在connect()函数里,可以不谢参数名称,但要写明参数类型。
- 多个信号可以连接同一个槽。
- 一个信号可以连接另外一个信号。
- 严格情况下,信号与槽的参数个数和类型需要一致,至少信号的参数不能少于槽的参数。
- 在使用信号与槽的类中,必须在类的定义中加入 Q_OBJECT。
- 当一个信号被发射后,与其关联的槽函数通常立即被执行,就像正常调用一个函数一样。只有信号关联的所有槽函数执行完毕后,才会执行发射信号处后面的代码。
例子:实现如下图所示功能
选中组件,右键单击‘Go to slot...‘之后:
qwdialog.h中:
#ifndef QWDIALOG_H
#define QWDIALOG_H
#include <QDialog>
namespace Ui {
class qwDialog;
}
class qwDialog : public QDialog
{
Q_OBJECT
public:
explicit qwDialog(QWidget *parent = nullptr);
~qwDialog();
private slots:
void on_chkBoxUnder_clicked(bool checked);
void on_chkBoxItalic_clicked(bool checked);
void on_chkBoxBlod_clicked(bool checked);
void setTextFontColor();
private:
Ui::qwDialog *ui;
};
#endif // QWDIALOG_H
qwdialog.cpp:
#include "qwdialog.h"
#include "ui_qwdialog.h"
qwDialog::qwDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::qwDialog)
{
ui->setupUi(this);
//槽函数是自定义的,不会自动与信号关联,所以需要在QWDialog 的构造函数中手动关联
connect(ui->rBtnBlack, SIGNAL(clicked()), this, SLOT(setTextFontColor()));
connect(ui->rBtnBlue, SIGNAL(clicked()), this, SLOT(setTextFontColor()));
connect(ui->rBtnRed, SIGNAL(clicked()), this, SLOT(setTextFontColor()));
}
qwDialog::~qwDialog()
{
delete ui;
}
//设置下划线槽函数
void qwDialog::on_chkBoxUnder_clicked(bool checked)
{
QFont font = ui->plainTextEdit->font();
font.setUnderline(checked);
ui->plainTextEdit->setFont(font);
}
//设置斜体槽函数
void qwDialog::on_chkBoxItalic_clicked(bool checked)
{
QFont font = ui->plainTextEdit->font();
font.setItalic(checked);
ui->plainTextEdit->setFont(font);
}
//设置粗体槽函数
void qwDialog::on_chkBoxBlod_clicked(bool checked)
{
QFont font = ui->plainTextEdit->font();
font.setBold(checked);
ui->plainTextEdit->setFont(font);
}
//设置字体颜色槽函数
void qwDialog::setTextFontColor()
{
QPalette plet = ui->plainTextEdit->palette();
if(ui->rBtnBlack->isChecked())
plet.setColor(QPalette::Text, Qt::black);
else if(ui->rBtnBlue->isChecked())
plet.setColor(QPalette::Text, Qt::blue);
else if(ui->rBtnRed->isChecked())
plet.setColor(QPalette::Text, Qt::red);
ui->plainTextEdit->setPalette(plet);
}
这里没有发现用 connect()函数进行几个 CheckBox 的信号与槽函数关联的操作。这些功能是如何实现的呢?
查看编译生成的 ui_qwdialog.h 文件。构造函数里调用的 setupUi() 是在 ui_qwdialog.h 中实现的。查看 setupUi() 函数的内容,也没有发现用 connect() 函数进行几个 CheckBox 信号与槽的关联的操作。秘密就在于:
QMetaObject::connectSlotsByName(qwDialog);
connectSlotsByName(qwDialog) 函数将搜索QWDialog 界面上的所有组件,将信号与槽函数匹配的信号和槽关联起来,它假设槽函数的名称是:
void on_<object name>_<signal name>(<signal parameters>);
例如,通过UI设计器的操作,为chkBoxUnder 的自动生成的槽函数是:
void on_chkBoxUnder_clicked(bool checked);
它就正好是 chkBoxUnder 的信号 clicked(bool) 的槽函数。那么,connectSlotsByName 就会将此信号与槽函数关联起来,如同执行了下面语句:
connect(chkBoxUnder, SIGNAL(clicked(bool)), this, SLOT(on_chkBoxUnder_clicked(bool));