【QT】QT從零入門教程(三):信號與槽

信號與槽

  信號和槽是QT中最基本的概念,也是QT中的核心機制。信號和槽是QT自行定義的一種通信機制,獨立於標準的C/C++語言,因此要正確的處理信號和槽,必須藉助moc(Meta Object Compiler)這一QT工具,該工具是個C++預處理程式,它爲高層次的事件處理自動生成所需要的附加代碼。

  信號與槽可以實現多信號與單個槽的連接,也可以實現單信號與多個槽的連接,甚至能實現信號間的連接,這時第一個信號發射後,第二個信號也將被即時發射。如果單信號連接多個槽,當這個信號被髮射時,與之相關的槽被激活的順序將是隨機的。

  所有從QObject或其子類(例如Qwidget)派生的類都能夠包含信號和槽。當對象改動其狀態時,信號就由該對象發射(emit)出去,而槽則用於接收信號。

  signals前面不可加public、private和protected進行修飾,它必須是void類型而且只聲明不定義。slots前面可以加修飾,它作爲普通的C++成員函數,能被正常調用。slots區域中的函數能有參數,但其參數不能有缺省值。 宏定義不能用在signal和slot的參數中。


  1、當信號與槽函數的參數數量相同時,它們參數類型要完全一致。

// 頭文件
#include <QtWidgets/QMainWindow>
#include "ui_ImageProcessing.h"

class ImageProcessing : public QMainWindow
{
    Q_OBJECT

public:
    ImageProcessing(QWidget *parent = Q_NULLPTR);

private:
    Ui::ImageProcessingClass ui;

signals:
    void iSignal(int b);     // 信號

private slots:
    void iSlot(int b);       // 槽函數
};
// cpp
#include <QMainWindow>
#include <QtGui>
#include <QtWidgets>
#include "MainWindow.h"

ImageProcessing::ImageProcessing(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
    connect(this, SIGNAL(iSignal(int)), this, SLOT(iSlot(int)));  // 連接信號和槽函數
    emit iSignal(5);        // 發射信號
}


void ImageProcessing::iSlot(int b)     // 槽函數定義
{
    QString qString;
    qDebug() << qString.number(b);
}


  2、當信號的參數與槽函數的參數數量不同時,只能是信號的參數數量多於槽函數的參數數量,且前面相同數量的參數類型應一致,信號中多餘的參數會被忽略。

// 頭文件
#include <QtWidgets/QMainWindow>
#include "ui_ImageProcessing.h"

class ImageProcessing : public QMainWindow
{
    Q_OBJECT

public:
    ImageProcessing(QWidget *parent = Q_NULLPTR);

private:
    Ui::ImageProcessingClass ui;

signals:
    void iSignal(int a,float b);   // 信號

private slots:
    void iSlot(int b);             // 槽函數
};
// cpp
#include <QMainWindow>
#include <QtGui>
#include <QtWidgets>
#include "MainWindow.h"

ImageProcessing::ImageProcessing(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
    connect(this, SIGNAL(iSignal(int,float)), this, SLOT(iSlot(int)));  // 連接信號和槽函數
    emit iSignal(1000, 0.3);    // 發射信號
} 


void ImageProcessing::iSlot(int b)    // 槽函數定義
{
    QString qString;
    qDebug() << qString.number(b);
}


  3、在不進行參數傳遞時,信號槽綁定時也是要求信號的參數數量大於等於槽函數的參數數量。這種情況一般是一個帶參數的信號去綁定一個無參數的槽函數。

// 頭文件
#include <QtWidgets/QMainWindow>
#include "ui_ImageProcessing.h"

class ImageProcessing : public QMainWindow
{
    Q_OBJECT

public:
    ImageProcessing(QWidget *parent = Q_NULLPTR);

private:
    Ui::ImageProcessingClass ui;

signals:
    void iSignal(int a,float b);

private slots:
    void iSlot();
};
// cpp
#include <QMainWindow>
#include <QtGui>
#include <QtWidgets>
#include "MainWindow.h"

ImageProcessing::ImageProcessing(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
    connect(this, SIGNAL(iSignal(int,float)), this, SLOT(iSlot()));
    emit iSignal(1000, 0.3);
}


void ImageProcessing::iSlot()
{
    QString qString = " Qt test (signals & slots) ";
    qDebug() << qString;
}


斷開連接

  當信號與槽沒有必要繼續保持關聯時,我們可以使用 disconnect 函數來斷開連接。其定義如下,用於斷開發射者中的信號與接收者中的槽函數之間的關聯。

bool QObject::disconnect(const QObject * sender, const char * signal, const Object * receiver, const char * member)

  有三種情況必須使用 disconnect() 函數:

  1、斷開與某個對象相關聯的任何對象。

  在某個對象中可能定義了一個或者多個信號時,這些信號與另外若干個對象中的槽相關聯,如果我們要切斷這些關聯,就可以利用這個方法,簡潔有效。

disconnect(myObject, 0, 0, 0) 

// myObject->disconnect()

  2、斷開與某個特定信號的任何關聯。

disconnect(myObject, SIGNAL(mySignal()), 0, 0) 

// myObject->disconnect(SIGNAL(mySignal()))

  3、斷開兩個對象之間的關聯。

disconnect(myObject, 0, myReceiver, 0) 

// myObject->disconnect(myReceiver)

  在 disconnect 函數中 0 可以用作一個通配符,分別表示任何信號、任何接收對象、接收對象中的任何槽函數。但是發射者 sender 不能爲 0,其它三個參數的值可以等於 0。

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