Qt帶參數(shù)的信號(hào)和槽函數(shù)舉例詳解
前言
在前面的文章中,我們已經(jīng)了解了Qt自帶的信號(hào)和槽函數(shù)以及自定義的信號(hào)和槽函數(shù),但是這些都是沒(méi)有帶參數(shù)的,其實(shí)信號(hào)和槽函數(shù)是可以帶有參數(shù)的。
1. 帶參數(shù)的信號(hào)和槽
Qt的信號(hào)和槽也是支持帶有參數(shù)的,同時(shí)也支持重載。
此處我們要求,信號(hào)函數(shù)的參數(shù)列表要和對(duì)應(yīng)連接的槽函數(shù)參數(shù)列表一致。當(dāng)信號(hào)觸發(fā)時(shí),調(diào)用槽函數(shù)的時(shí)候,信號(hào)函數(shù)的實(shí)參就能被傳遞到槽函數(shù)的形參當(dāng)中。
1.2 參數(shù)匹配的信號(hào)和槽函數(shù)
下面我回寫一個(gè)程序,程序的功能是通過(guò)兩個(gè)按鈕來(lái)傳遞參數(shù)人窗口的標(biāo)題發(fā)生改變。
#include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); connect(this,&Widget::mySignal,this,&Widget::handle); } Widget::~Widget() { delete ui; } void Widget::handle(QString s) { this->setWindowTitle(s); } void Widget::on_pushButton_clicked() { emit mySignal("被按鈕1調(diào)用"); } void Widget::on_pushButton_2_clicked() { emit mySignal("被按鈕2調(diào)用"); }
頭文件:
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QString> QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); signals: void mySignal(QString s); public slots: void handle(QString s); private slots: void on_pushButton_clicked(); void on_pushButton_2_clicked(); private: Ui::Widget *ui; }; #endif // WIDGET_H
當(dāng)信號(hào)函數(shù)和槽函數(shù)參數(shù)匹配時(shí),并不會(huì)發(fā)生什么,那么現(xiàn)在讓我們來(lái)看看參數(shù)不匹配的情況下是怎么樣的吧。
1.2 參數(shù)不匹配的信號(hào)和槽
參數(shù)不匹配的情況可以分為三種:
- 槽函數(shù)的參數(shù)數(shù)量大于信號(hào)函數(shù)的參數(shù)數(shù)量但參數(shù)類型相同
- 信號(hào)函數(shù)的參數(shù)數(shù)量大于槽函數(shù)的參數(shù)數(shù)量但參數(shù)類型相同
- 信號(hào)函數(shù)和槽函數(shù)的參數(shù)數(shù)量相同但參數(shù)類型不同
下面開(kāi)始逐個(gè)講解
1.2.1 槽函數(shù)參數(shù)數(shù)量大于信號(hào)函數(shù)
#include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); connect(this,&Widget::mySignal,this,&Widget::handle); } Widget::~Widget() { delete ui; } void Widget::handle(QString s1,QString s2) { this->setWindowTitle(s1); } void Widget::on_pushButton_clicked() { emit mySignal("被按鈕1調(diào)用"); } void Widget::on_pushButton_2_clicked() { emit mySignal("被按鈕2調(diào)用"); }
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QString> QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); signals: void mySignal(QString s1); public slots: void handle(QString s1,QString s2); private slots: void on_pushButton_clicked(); void on_pushButton_2_clicked(); private: Ui::Widget *ui; }; #endif // WIDGET_H
可以看到,編譯器報(bào)錯(cuò)了,這也就說(shuō)明了槽函數(shù)參數(shù)數(shù)量大于信號(hào)函數(shù)是不可以的。
1.2.2 信號(hào)函數(shù)參數(shù)數(shù)量大于槽函數(shù)
#include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); connect(this,&Widget::mySignal,this,&Widget::handle); } Widget::~Widget() { delete ui; } void Widget::handle(QString s) { this->setWindowTitle(s); } void Widget::on_pushButton_clicked() { emit mySignal("被按鈕1調(diào)用",""); } void Widget::on_pushButton_2_clicked() { emit mySignal("被按鈕2調(diào)用",""); }
可以正常運(yùn)行,也就表明信號(hào)函數(shù)的參數(shù)個(gè)數(shù)超過(guò)槽函數(shù)的參數(shù)個(gè)數(shù)參數(shù)個(gè)數(shù)是可以正常使用的,但是反過(guò)來(lái)就是不行,槽函數(shù)的參數(shù)個(gè)數(shù)大于信號(hào)函數(shù)的參數(shù)個(gè)數(shù),無(wú)法編譯通過(guò)。
個(gè)數(shù)的不一致,槽函數(shù)就會(huì)按照參數(shù)的順序拿到信號(hào)的前N個(gè)參數(shù),確保槽函數(shù)的每個(gè)之都是有值。
思考下,為什么會(huì)這樣呢?又為什么不要求參數(shù)的個(gè)數(shù)嚴(yán)格一致呢?
如果我們要求參數(shù)的個(gè)數(shù)完全一致,就意味著信號(hào)綁定到槽函數(shù)的要求變高了,換言之當(dāng)下的規(guī)則允許信號(hào)和槽函數(shù)之間的綁定更加的靈活,更多的信號(hào)可以綁定到這個(gè)槽函數(shù)上了。
1.2.3 信號(hào)函數(shù)和槽函數(shù)的參數(shù)類型不同
會(huì)報(bào)錯(cuò)~
帶有參數(shù)的信號(hào)要求信號(hào)的參數(shù)和槽函數(shù)的參數(shù)類型是一致的。
2.知識(shí)補(bǔ)充
2.1 Q_OBJECT
Qt中如果要讓某個(gè)類能夠使用信號(hào)槽,必須要在類最開(kāi)始的地方,寫下Q_OBJECT宏
使用ALT加右鍵點(diǎn)擊
就可以看到里面的內(nèi)容了,實(shí)際上這里還可以再進(jìn)一步展開(kāi),最終會(huì)得到一系列很復(fù)雜的代碼。
2.1 信號(hào)槽多對(duì)多
所謂的信號(hào)槽,終究要解決的問(wèn)題就是響應(yīng)用戶的操作。
信號(hào)槽,其實(shí)在GUI開(kāi)發(fā)的各種框架中是一個(gè)比較"有特色"的存在。
大部分的GUI開(kāi)發(fā)框架都是一對(duì)一的存在
一個(gè)事件只能對(duì)應(yīng)一個(gè)處理函數(shù),一個(gè)處理函數(shù)也只能對(duì)應(yīng)到一個(gè)事件上。
就比如網(wǎng)頁(yè)開(kāi)發(fā)中的JS,網(wǎng)頁(yè)開(kāi)發(fā)中響應(yīng)用戶操作,主要就是掛回調(diào)函數(shù)。
而Qt專門搞了一個(gè)單獨(dú)的connect來(lái)完成信號(hào)槽的連接
Qt信號(hào)槽的設(shè)計(jì),理想很美好,現(xiàn)實(shí)很骨感
該機(jī)制主要的效果就是:
- 解耦合,把觸發(fā)用戶操作的控件和處理對(duì)應(yīng)用戶的操作邏輯解耦合。
- 多對(duì)多的效果:一個(gè)信號(hào)可以connect到多個(gè)槽函數(shù)上,一個(gè)槽函數(shù),也可以被多個(gè)信號(hào)connect。
那么什么是多對(duì)多呢?
以選課為例,一個(gè)學(xué)生可以選擇多門課,一門課可以被多名學(xué)生選擇這種。
多對(duì)多真的實(shí)用嗎?
答案是否定的,在實(shí)際的開(kāi)發(fā)過(guò)程中,隨著大家的經(jīng)驗(yàn)越來(lái)越多,其實(shí)在GUI開(kāi)發(fā)的過(guò)程中,多對(duì)多就是一個(gè)偽需求,實(shí)際的開(kāi)發(fā)中很少用到,絕大情況下一對(duì)一就夠用了。
所以一些新的圖形化開(kāi)發(fā)框架,很少有再繼續(xù)支持這種多對(duì)多的了~
3. 總結(jié)
本文我們了解了帶參數(shù)的信號(hào)和槽函數(shù),得知了槽函數(shù)會(huì)接受到來(lái)自信號(hào)的參數(shù)。且這個(gè)參數(shù)也是有要求的,信號(hào)函數(shù)的參數(shù)個(gè)數(shù)可以大于槽函數(shù)的參數(shù)個(gè)數(shù),但是類型必須相同。
到此這篇關(guān)于Qt帶參數(shù)的信號(hào)和槽函數(shù)的文章就介紹到這了,更多相關(guān)Qt帶參數(shù)信號(hào)和槽函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)單元測(cè)試的示例詳解
單元測(cè)試(unit testing),是指對(duì)軟件中的最小可測(cè)試單元進(jìn)行檢查和驗(yàn)證。這篇文章主要為大家介紹了C語(yǔ)言實(shí)現(xiàn)單元測(cè)試的方法,需要的可以參考一下2022-09-09C語(yǔ)言從猜數(shù)字游戲中理解數(shù)據(jù)結(jié)構(gòu)
猜數(shù)字是興起于英國(guó)的益智類小游戲,起源于20世紀(jì)中期,一般由兩個(gè)人或多人玩,也可以由一個(gè)人和電腦玩。游戲規(guī)則為一方出數(shù)字,一方猜,今天我們來(lái)用這個(gè)游戲案例理解數(shù)據(jù)結(jié)構(gòu)2022-04-04Microsoft?Visual?C++進(jìn)行調(diào)試的方法實(shí)現(xiàn)
VS功能極其強(qiáng)大,使用極其便利,本文主要介紹了Microsoft?Visual?C++進(jìn)行調(diào)試的方法實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-06-06C語(yǔ)言通過(guò)二分查找實(shí)現(xiàn)猜數(shù)字游戲
這篇文章主要為大家詳細(xì)介紹了在C語(yǔ)言中如何通過(guò)二分查找思想編寫一個(gè)簡(jiǎn)單的猜數(shù)字游戲,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-02-02C語(yǔ)言詳解格式控制符scanf與printf的輸入輸出
這篇文章主要介紹了C語(yǔ)言格式控制符中輸入scanf()和輸出printf()的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2022-04-04C語(yǔ)言熱門考點(diǎn)結(jié)構(gòu)體與內(nèi)存對(duì)齊詳解
在掌握基本的結(jié)構(gòu)體使用后,我們?cè)诿嬖嚭痛笮捅荣愔谐3?huì)遇到一個(gè)熱門考點(diǎn):結(jié)構(gòu)體內(nèi)存對(duì)齊,也就是計(jì)算結(jié)構(gòu)體大小。接下來(lái)請(qǐng)跟著筆者一起來(lái)學(xué)習(xí)這塊知識(shí)點(diǎn)吧2021-10-10Visual Studio中scanf函數(shù)報(bào)錯(cuò)的幾種解決方法
本文主要介紹了Visual Studio中scanf函數(shù)報(bào)錯(cuò)的幾種解決方法,文中通過(guò)圖文示例介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-03-03c語(yǔ)言實(shí)現(xiàn)數(shù)組循環(huán)左移m位
這篇文章主要介紹了c語(yǔ)言實(shí)現(xiàn)數(shù)組循環(huán)左移m位,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07