目錄
1,信號與槽的介紹
2,信號與槽的運用
3,自定義信號
1,信號與槽的介紹
????????在Qt框架中,信號與槽機制是一種用于對象間通信的強大工具。它是在Qt中實現事件處理和回調函數的主要方法。
-
信號:窗口中,當某個事件發生時,一個類可能會發出一個信號。例如,按鈕被點擊、窗口被關閉等。信號是自動觸發的,無需用戶干預,它的本質就是事件。
-
槽:槽是用來接收并處理信號的函數。槽函數執行特定的操作來響應接收到的信號。簡單來說,對信號做出的響應動作就稱之為槽。通常,會將槽與信號關聯起來,以便處理。槽的本質是一種回調函數,在Qt5以及更高版本中,槽函數與普通函數基本沒啥區別。
????????在Qt中,用戶和控件的每次交互過程稱為一個事件。比如 “用戶點擊按鈕” 是?個事件,“用戶關閉窗口”?也是?個事件。每個事件都會發出一個信號,信號發出后將會進行槽處理,例如用戶點擊按鈕會發出 “按鈕被點擊” 的信號,用戶關閉窗口會發出 “窗口被關閉”?的信號,然后接收該信號的槽將會執行對應的處理函數。
2,信號與槽的運用
認識QObject:
????????QWidget是 Qt 框架中的一個核心基類,主要用于實現對象間的通信機制(如信號與槽機制),并提供基礎的對象管理功能,如事件處理、幾何坐標管理、內置信號和槽等,這一點通過Qt的不斷學習我們會諑漸認識到。
? ? ? ? Qt系統中提供的類本身是存在一定的繼承關系。如QPushButton、QLineEdit、QTextEdit、QLabel等,它們都有共同的父類,即QWidget,它是一個控件,也就是圖形化界面中的小部件。QWidget還有一個父類——QObject。可以說所有的事務類都繼承QObject。
? ? ? ? 在Qt中,每個繼承自QWidget(或者更準確地說,繼承自QObject)的部件(Widget)都內置了一系列預定義的信號和槽,例如,QPushButton有一個clicked()信號,當按鈕被點擊時會發出這個信號。
認識connect函數:
????????在 Qt 中,QObject 類提供了一個靜態成員函數 connect(),該函數用于連接信號和槽。
函數格式:
? ? ? ? 形式 一:connect(const QObject *sender,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const char *signal,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ????????????const QObject *receiver,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const char *method,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Qt::ConnectionType type = Qt::AutoConnection)
???????? ? ? ? 形式二:connect(const QObject* sender,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const QMetaMethod& signal,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const QObject* receiver,?????????????????????????????????????const QMetaMethod& method,
? ? ? ? ? ? ? ? ? ? ? ????????? ? ? ?Qt::ConnectionType type = Qt::AutoConnection);參數說明:???????
????????sender:發出信號的對象。
????????signal:要連接的信號。
????????receiver:接收信號并處理它的對象。
????????method:槽,即響應信號的方法。
????????type:用于指定關聯方式,暫時先不做考慮。
? ? ? ? 形式二中第二個參數和第四個參數使用函數指針代替字符串來指定信號和槽,使編譯器在編譯期檢查信號和槽的簽名是否兼容,從而減少運行時錯誤。
connect運用樣例:
? ? QPushButton* pushButton = new QPushButton(this);
? ? pushButton->setText("Qt");
? ? connect(pushButton, &QPushButton::clicked, this, &Widget::handleClick);? ? 槽函數的定義:
????void Widget::handleClick()
? ? {
? ? ? ? if (pushButton->text() == QString("Qt")) {
? ? ? ? ? ? pushButton->setText("Hello Qt");
? ? ? ? }
? ? ? ? else {
? ? ? ? ? ? pushButton->setText("Qt");
? ? ? ? }
? ? }
? ? ? ? 注意:通過圖形化界面生成的信號與槽機制(.ui文件進行操作)時,槽函數的名稱不能隨意更改,因為 .ui 文件內部專門生成的槽函數名來連接信號的,若是修改了函數名,它將不能正常連接。
3,自定義信號
? ? ? ? 自定義信號在實際開發中很少遇到,因為內置的信號基本包含了用戶的事件相關操作。這里知道即可。
? ? ? ? 信號是一種特殊的函數機制,它的返回值必須是void,參數可有可無。這個函數的定義是 Qt 在編譯過程中自動生成的,因此,自定義信號只需寫出函數聲明,并告訴 Qt 這是一個 “信號” 即可。
? ? ? ? 自定義信號的運用需要使用 signals(自定義信號的標志)和 emit(發送信號)關鍵字。內置信號不需要手動觸發(也可以使用emit發送,改變觸發模式),用戶在 GUI 進行相關操作時,就會自動觸發信號。發送信號的代碼已經內置到 Qt 框架中了。
樣例:
??????widget.h文件里的Widget類中添加以下代碼:
? ? ? ????????signals:
? ? ? ? ? ? ? ????????void mySignal(const QString&); ?// 自定義信號mySignal()
? ? ? ? ? ? ? ????????void handleMySignal(const QString&); // 槽函數? ? ? 在widget.cpp文件中添加以下代碼:
? ? ? ? ? ? ? ?// 連接信號與槽
??????????????connect(this, &Widget::mySignal, this, &Widget::handleMySignal);
??????????????// 發送出自定義的信號,類似內置信號中用戶點擊按鈕然后自動發送信號。
??????????????emit mySignal("處理自定義信號");// 發送信號的操作是根據用戶操作的情況進行的
????????????void Widget::handleMySignal(const QString& text)// 參數text="處理自定義信號"
????????????{
? ? ??????? ? ? this->setWindowTitle(text);
??????????? }
????????注意:Qt5及更高的版本中,不加 emit 也能發送信號,但建議還是加上,使代碼可讀性更高。自定義信號的參數可以比槽函數的參數數量多,但參數之間的類型必須一樣,且槽函數的參數不能比信號的參數多。因為一個槽函數可以綁定多個信號,若嚴格要求參數個數一致,就意味著信號綁定到槽函數的要求就變高了,而這樣設置是為了使更多的信號綁定到一個槽函數上。