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