- 信號(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));