天天看點

lesson2-信号與槽機制

一、信号與槽的了解

1、什麼是信号和槽?

在許多GUI工具中,每一個視窗部件都有一個回調函數用于響應他們能夠觸發的動作,這些回調函數通常是一個指向某個函數的指針。指針是一個相對麻煩的概念,在Qt中信号與槽取代了這些淩亂的函數指針,使得程式的編寫更為簡單。

當一個對象發生改變的時候,信号就由這個對象發射出去,這就是這個對象要做的全部事情,它并不知道另一端是誰在接收信号,這個過程就是真正的資訊封裝,實作了絕對的安全。

槽用于接收信号,它們是普通的c++成員函數,它們并不知道是否有信号與自己關聯,而且對象并不了解通信機制

在Qt中,當點選一個按鈕的時候,這個按鈕會發出一個信号,而這個信号會傳遞給另外一個對象,接收到信号的對象會産生相應的動作,這就是信号與槽的機制

2、信号與槽的關聯

1)、信号與槽通過

QObject::connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::Connection type=Qt::AutoCompatConnection)産生關聯

sender,信号的發送者

signal,待發送的信号

receiver,信号的接收者

method,槽函數

type,信号與槽的關聯方式

2)、type有3種類型

Qt::DirectConnection,信号發送後立即傳遞給槽,隻有槽函數執行完畢傳回之後,發送信号"emit"之後的代碼才能被執行

Qt::QueueConnection,信号發送後排隊,直到事件循環有能力将它傳遞給槽,而不管槽函數有沒有執行,發送信号"emit"之後的代碼

立即被執行

Qt::AutoCompatConnection,如果信号和槽在同一個線程,等同于Qt::DirectConnection;如果信号和槽不在同一個線程,那麼等同于

Qt::QueueConnection。

二、信号與槽的執行個體

1、信号

當對象的内部狀态發生改變,信号就被發射,隻有定義了一個信号的類和它的子類才能發射這個信号。例如QPushButton類中就預定義了clicked信号,當按鈕被點選時,就會發射clicked信号。

在Qt中除了系統預定義的信号外,也可以自定義信号

信号的聲明在頭檔案中,以關鍵字signals開頭

signals:

 void signals();

 void signals(int x);

這裡面有兩個信号,最然名字一樣,但是攜帶的參數不一樣,有點類似于函數的重載。

信号類似一個普通的C++函數,但是它沒有實體,隻有一個空殼,而且它的傳回值永遠是void,不要期待從信号中傳回有用的資訊。信号聲明好以後,有moc工具自動産生,是以不應該放在.cpp檔案中。

系統預定義信号一般會自動發射,不需要我們關心,如果需要手動發射信号,可以這樣寫emit signals();

2、槽

槽是普通的C++成員函數,可以被正常的調用,很多信号可以與槽進行關聯。既然槽是一個普通的成員函數,那麼它也有權限。是以有3種類型的槽函數,public slots,private slots, protect slots

槽函數的申明也是在頭檔案中

private slots:

  void mySlot1();

  void mySlot1(int x);

在信号和槽函數的聲明之前,必須加一個宏Q_OBJECT,隻有這樣Qt才會認識它們

3、元對象工具

moc工具會對c++檔案中的類的聲明進行初始化,自動産生用于初始化元對象的c++代碼,元對象包含全部的信号和槽,以及指向這些名字的指

針。

moc讀取c++源檔案,如果發現有Q_OBJECT宏聲明的類,它就會生成另外的c++源檔案。moc工具不擴充#define,是以信号和槽函數中不能有宏定義

4、關聯

信号與槽的關聯通過函數connect

btn = new QPushButton();

lab = new QLabel();

connect(btn, SIGNAL(clicked()), lab, SLOT(clear()))

信号需要使用宏SIGNAL(),槽函數需要使用宏SLOT();

信号和槽的參數一定要一緻;

當信号和槽屬于同一對象時,信号的接收者可以省略

connect(btn, SIGNAL(clicked()), SLOT(showMenu()))

信号和槽應該注意的問題

1)、構造函數不能在信号和槽的區域内

2)、函數指針不能做為信号和槽的參數

3)、信号和槽不能有預設的參數

4)、信号和槽不能帶有模闆類參數

5)、嵌套的類不能位于信号和槽區域,也不能有信号和槽

繼續閱讀