QT入門之信號與槽

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

關於信號與槽的使用,有以下一些規則需要注意:

  1. 一個信號可以連接多個槽,槽函數按照建立連接時的順序一次執行。當信號與槽函數帶有參數時,在connect()函數裏,可以不謝參數名稱,但要寫明參數類型。
  2. 多個信號可以連接同一個槽。
  3. 一個信號可以連接另外一個信號。
  4. 嚴格情況下,信號與槽的參數個數和類型需要一致,至少信號的參數不能少於槽的參數。
  5. 在使用信號與槽的類中,必須在類的定義中加入 Q_OBJECT。
  6. 當一個信號被髮射後,與其關聯的槽函數通常立即被執行,就像正常調用一個函數一樣。只有信號關聯的所有槽函數執行完畢後,纔會執行發射信號處後面的代碼。

例子:實現如下圖所示功能

選中組件,右鍵單擊‘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));

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章