Qt中connect()函數(shù)及用法詳解
一、基本概念
要想了解connect() 函數(shù),要先知道在Qt中什么是什么是信號(SIGNAL)和槽(SLOT)。
信號(SIGNAL):指在特定情況下發(fā)射的通知。比如當(dāng)我們點擊了用戶界面的一個按鈕之后就發(fā)射了一個信號。
槽(SLOT):是指對信號進行響應(yīng)的函數(shù)。也就是我們點擊了一個按鈕后我們要實現(xiàn)的功能。
那么connect() 函數(shù)就是Qt 框架中用于將信號(SIGNAL)和槽(SLOT)關(guān)聯(lián)起來的核心函數(shù)。
二、用法
1.舊版用法(Qt4和早期Qt5)
connect(sender, SIGNAL(signalName()), receiver, SLOT(slotName()));
- sender:發(fā)射信號的對象名稱
- signalName():信號名稱
- receiver:接收信號的對象名稱,一般情況下為槽函數(shù)所屬對象,寫this即可
- slotName():槽函數(shù)名稱
示例:
connect(button, SIGNAL(clicked()), this, SLOT(handleButtonClicked()));
注意: 如果信號與槽函數(shù)帶參數(shù)還需要在函數(shù)括號內(nèi)標出。
2.新版用法(推薦)
connect(sender, &SenderClass::signalName, receiver, &ReceiverClass::slotName);
這里引入了基于函數(shù)指針的語法,使得編譯器可以進行更好的類型檢查。但是這里有一個問題:與舊版的寫法不同的是,信號與槽函數(shù)的參數(shù)怎么辦?
首先我們知道,在 Qt 的信號與槽機制中,槽函數(shù)的參數(shù)不能多于信號的參數(shù)。也就是說,信號的參數(shù)可以多于槽的參數(shù),且槽函數(shù)的參數(shù)必須是信號參數(shù)的一個子集。那么就可以分為如下三種情況:
1.信號和槽函數(shù)具有相同數(shù)量和類型的參數(shù)。這時可以直接連接且無需出現(xiàn)函數(shù)參數(shù):
connect(lineEdit, &QLineEdit::textChanged, this, &Widget::do_textChanged);
在上面示例中,信號textChanged(QString)和槽函數(shù)do_textChanged(QString)參數(shù)相同。
2.信號的參數(shù)多于槽函數(shù)的參數(shù)。槽函數(shù)將忽略信號的多余參數(shù),這個特性允許你在信號和槽參數(shù)不完全匹配的情況下,仍然能夠正常工作。正常情況下,不推薦把槽函數(shù)設(shè)計為overload型。
3.某些信號的參數(shù)有默認值。也就是說同一信號的參數(shù)分為有參數(shù)和無參數(shù),如QCheckBox的clicked()信號和clicked(bool)信號。這時connect()函數(shù)有兩種寫法:
a.設(shè)置不同名字的槽函數(shù):
//槽函數(shù) void do_checked(bool checked); void do_checked_NoParam(); //connect()函數(shù) connect(checkBox, &QCheckBox::clicked, this, &Widget::do_checked); connect(checkBox, &QCheckBox::clicked, this, &Widget::do_checked_NoParam);
b.使用模板函數(shù)qOverload()來明確參數(shù)類型:
connect(checkBox, &QCheckBox::clicked, this, qOverload<bool>(&Widget::do_checked)); connect(checkBox, &QCheckBox::clicked, this, qOverload<>(&Widget::do_checked));
3.自動連接(無需使用connect()函數(shù))
在構(gòu)建項目時,若勾選了“Generate form”字段,則會生成一個后綴為“.ui”的文件。
那么在ui設(shè)計界面種可以選中一個對象,右鍵選擇“Go to slot”或者“轉(zhuǎn)到槽”,在彈出的對話框中再選擇信號,那么就會自動生成一個槽函數(shù)。如果槽函數(shù)的名稱符合相應(yīng)的格式,Qt 會在運行時通過setupUi(this)自動生成connect()函數(shù)完成連接。
Dialog::Dialog(QWidget *parent) : QDialog(parent) , ui(new Ui::Dialog) { //由go to slot生成的槽函數(shù)可以自動關(guān)聯(lián) ui->setupUi(this); //自定義槽函數(shù)需要手動關(guān)聯(lián) connect(ui->radioButtonBlack,SIGNAL(clicked()),this,SLOT(do_setFontColor())); } //自動生成的槽函數(shù)格式:void on_<objectName>_<signalName>(){} void Widget::on_btnCal_clicked() { ... } //手動寫的槽函數(shù) void Widget::do_setFontColor() { ... }
當(dāng)然在設(shè)計一些復(fù)雜功能時,自動連接方法就不太適用了。
4.Lambda表達式(Qt5.4)
lambda 表達式提供了一種非常靈活的方式來處理信號。有如下幾個優(yōu)點:
- 可以直接在連接語句中定義信號處理邏輯,無需在類中定義額外的槽函數(shù)。這在處理簡單邏輯時尤其方便。
- 避免為每個信號處理邏輯定義新的槽函數(shù),減少命名空間污染。
- 允許你在處理信號參數(shù)時,捕獲外部變量或定義額外的處理邏輯。
基本格式如下:
connect(sender, &SenderClass::signalName, [lambda expression]);
舉個栗子對比理解一下:
//方法一:使用槽函數(shù)指針連接 void processData(int value, QString message) { if (value > 10) { qDebug() << "Value is greater than 10:" << value << ", Message:" << message; } else { qDebug() << "Value is 10 or less:" << value; } } QObject::connect(&sender, &SenderClass::signalName, this, &ReceiverClass::processData);
//方法二:使用lambda表達式連接 QObject::connect(&sender, &SenderClass::signalName, [this](int value, QString message) { if (value > 10) { qDebug() << "Value is greater than 10:" << value << ", Message:" << message; } else { qDebug() << "Value is 10 or less:" << value; } });
三、斷開連接disconnect()
1.為什么使用disconnect()
使用connect()函數(shù)可以關(guān)聯(lián)信號與槽,那么刪除connect()函數(shù)不就可以斷開連接了嗎?
其實不然!我們最好使用官方的 disconnect() 函數(shù)來解除信號與槽的連接。原因有如下幾點:
a.動態(tài)控制信號和槽的連接
有時你需要在運行時動態(tài)地控制信號和槽的連接。例如,你可能需要在某些情況下連接信號和槽,而在其他情況下斷開它們。在這種情況下,使用 disconnect() 函數(shù)可以讓你在需要時靈活地斷開連接,而不需要修改代碼來刪除 connect() 調(diào)用。
b.保持代碼的結(jié)構(gòu)和可讀性
connect() 調(diào)用通常在類的構(gòu)造函數(shù)或初始化方法中設(shè)置,表示對象之間的關(guān)系和交互。將連接和斷開連接的邏輯分開可以使代碼更清晰、更具結(jié)構(gòu)性。如果直接刪除 connect() 調(diào)用,代碼邏輯可能會變得混亂且難以維護。
c. 方便的調(diào)試和維護
使用 disconnect() 可以更方便地調(diào)試和維護代碼。你可以在調(diào)試時臨時斷開某些連接,而無需刪除和重新添加 connect() 調(diào)用。這樣可以避免錯誤,并更容易地還原代碼。
d. 多次連接和斷開
在某些情況下,你可能會多次連接和斷開相同的信號和槽。例如,當(dāng)某個條件發(fā)生變化時,你希望斷開以前的連接并建立新的連接。使用 disconnect() 可以確保你正確地斷開之前的連接,而不會遺留下不需要的連接。
2.使用方法
a.解除與一個發(fā)射者所有信號的連接
disconnect(myObject, nullptr, nullptr, nullptr); myObject->disconnect();
b.解除與一個特定信號的所有連接
disconnect(myObject, SIGNAL(mySignal), nullptr, nullptr); myObject->disconnect(SIGNAL(mySignal));
c.解除與一個特定接收者的所有連接
disconnect(myObject, nullptr, myReceiver, nullptr); myObject->disconnect( myReceiver);
d.解除特定的一個信號與槽的連接
disconnect(lineEdit, &QLineEdit::textChanged, label, &QLabel::setText);
四、細節(jié)問題
1. 一個信號可以連接到多個槽,所有連接的槽都會在信號發(fā)出時依次被調(diào)用。
connect(sender, &SenderClass::signalName, receiver1, &ReceiverClass1::slotName); connect(sender, &SenderClass::signalName, receiver2, &ReceiverClass2::slotName);
2. 信號和槽機制是單向的,即信號發(fā)出時會調(diào)用槽函數(shù),但槽函數(shù)中發(fā)出的信號不會自動調(diào)用其他槽函數(shù),除非你明確連接了這些信號和槽。
到此這篇關(guān)于Qt中connect()函數(shù)的文章就介紹到這了,更多相關(guān)Qt connect()函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
如何在 clion 運行多個 main 函數(shù)(方法詳解)
這篇文章主要介紹了如何在 clion 運行多個 main 函數(shù),本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-08-08C語言庫函數(shù)qsort及bsearch快速排序算法使用解析
這篇文章主要為大家介紹了C語言庫函數(shù)qsort及bsearch快速排序算法的使用示例解析2022-02-02C++讀取WAV音頻文件的頭部數(shù)據(jù)的實現(xiàn)方法
這篇文章主要介紹了C++讀取WAV音頻文件的頭部數(shù)據(jù)的實現(xiàn)方法的相關(guān)資料,希望通過本文能幫助到大家,讓大家實現(xiàn)這樣的方法,需要的朋友可以參考下2017-10-10