Qt Connect 訊號 槽

Rocky_Ansi發表於2015-03-06

     訊號和槽機制是 QT 的核心機制 。訊號和槽是一種高階介面,應用於物件之間的通訊,它是 QT 的核心特性,也是 QT 區別於其它工具包的重要地方。訊號和槽是 QT 自行定義的一種通訊機制,它獨立於標準的 C/C++ 語言,因此要正確的處理訊號和槽,必須藉助一個稱為 moc(Meta Object Compiler)的 QT 工具,該工具是一個 C++ 預處理程式它為高層次的事件處理自動生成所需要的附加程式碼。 

在QT中,connect()函式是關聯部件的動作與執行的函式。

  在啟動函式中進行設定,並非是在訊號槽函式中進行設定。也就是一啟動就關聯好,如果放在訊號槽中,則進行第一次動作,進行關聯,第二次才能實行執行的函式。
同時,connect()函式中的SLOT()中的槽函式,必須在標頭檔案定義中需要放在public slot或者private slot函式中。否則不能實現,編譯錯誤。
   訊號和槽能攜帶任意數量和任意型別的引數(型別要匹配),他們是型別完全安全的,不會像回撥函式那樣產生 core dumps。
 
  所有從 QObject 或其子類 ( 例如 Qwidget) 派生的類都能夠包含訊號和槽。當物件改變其狀態時,訊號就由該物件發射 (emit) 出去,它不知道另一端是誰在接收這個訊號。這就是真正的資訊封裝,它確保物件被當作一個真正的軟體元件來使用。槽用於接收訊號,但它們是普通的物件成員函式。一個槽並不知道是否有任何訊號與自己相連線。而且,物件並不瞭解具體的通訊機制

 

  槽(Slots):

    槽是普通的 C++ 成員函式,可以被正常呼叫,它們唯一的特殊性就是很多訊號可以與其相關聯。當與其關聯的訊號被髮射時,這個槽就會被呼叫。槽可以有引數,但槽的引數不能有預設值。

  既然槽是普通的成員函式,因此與其它的函式一樣,它們也有存取許可權。槽的存取許可權決定了誰能夠與其相關聯。同普通的 C++ 成員函式一樣,槽函式也分為三種型別,即 public slots、private slots 和 protected slots。 // 與C++三種許可權作用相同;;

  • public slots:在這個區內宣告的槽意味著任何物件都可將訊號與之相連線。這對於元件程式設計非常有用,你可以建立彼此互不瞭解的物件,將它們的訊號與槽進行連線以便資訊能夠正確的傳遞。
  • protected slots:在這個區內宣告的槽意味著當前類及其子類可以將訊號與之相連線。這適用於那些槽,它們是類實現的一部分,但是其介面介面卻面向外部。
  • private slots:在這個區內宣告的槽意味著只有類自己可以將訊號與之相連線。這適用於聯絡非常緊密的類。

  槽也能夠宣告為虛擬函式,這也是非常有用的。// 被繼承使用;;

 

  訊號(Signals):

    當某個訊號對其客戶或所有者發生的內部狀態發生改變,訊號被一個物件發射(emit)。只有 定義過這個訊號的類及其派生類能夠發射這個訊號。當一個訊號被髮射時,與其相關聯的槽將被立刻執行,就象一個正常的函式呼叫一樣。訊號 - 槽機制完全獨立於任何 GUI 事件迴圈。只有當所有的槽返回以後發射函式(emit)才返回。 如果存在多個槽與某個訊號相關聯,那麼,當這個訊號被髮射時,這些槽將會一個接一個地 執行,但是它們執行的順序將會是隨機的、不確定的,我們不能人為地指定哪個先執行、哪 個後執行。

訊號的宣告是在標頭檔案中進行的,QT 的 signals 關鍵字指出進入了訊號宣告區,隨後即可 宣告自己的訊號。

 

  訊號與槽關聯 Connect()函式:

    通過呼叫 QObject 物件的 connect 函式來將某個物件的訊號與另外一個物件的槽函式相關聯,這樣當發射者發射訊號時,接收者的槽函式將被呼叫 

      一般使用一下兩種格式:

1、 QMetaObject::Connection QObject::connect(const QObject * sender, const char * signal, const QObject * receiver,

const char * method, Qt::ConnectionType type = Qt::AutoConnection) [static]

QLabel *label = new QLabel;     QScrollBar *scrollBar = new QScrollBar;     QObject::connect(scrollBar, SIGNAL(valueChanged(int)),label, SLOT(setNum(int))); // 使用 SIGNAL() 與 SLOT() 巨集;; 2、QMetaObject::Connection QObject::connect(const QObject * sender, PointerToMemberFunction signal, const QObject * receiver, PointerToMemberFunction method, Qt::ConnectionType type = Qt::AutoConnection) [static]     QLabel *label = new QLabel;     QLineEdit *lineEdit = new QLineEdit;     QObject::connect(lineEdit, &QLineEdit::textChanged,label, &QLabel::setText); // 使用例項地址進行引用訊號 與 槽

  

    當訊號與槽沒有必要繼續保持關聯時,我們可以使用 disconnect 函式來斷開連線。如下定義:

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

       

   1、Disconnect everything connected to an object's signals:

    disconnect(myObject, 0, 0, 0);
    等於  myObject->disconnect();

   2、Disconnect everything connected to a specific signal:
    disconnect(myObject, SIGNAL(mySignal()), 0, 0);
  等於 
myObject->disconnect(SIGNAL(mySignal()));

  3、Disconnect a specific receiver:
    disconnect(myObject, 0, myReceiver, 0);
  等於 myObject->disconnect(myReceiver);

0 may be used as a wildcard, meaning "any signal", "any receiving object", or "any slot in the receiving object", respectively.

The sender may never be 0. (You cannot disconnect signals from more than one object in a single call.)

If signal is 0, it disconnects receiver and method from any signal. If not, only the specified signal is disconnected.

If receiver is 0, it disconnects anything connected to signal. If not, slots in objects other than receiver are not disconnected.

If method is 0, it disconnects anything that is connected to receiver. If not, only slots named method will be disconnected, and all other slots are left alone. The method must be 0 if receiver is left out, so you cannot disconnect a specifically-named slot on all objects.

 

相關文章