柚子快報(bào)邀請(qǐng)碼778899分享:Qt——信號(hào)和槽
柚子快報(bào)邀請(qǐng)碼778899分享:Qt——信號(hào)和槽
一.信號(hào)和槽概述
談及信號(hào),很容易聯(lián)想到在Linux系統(tǒng)中所分享到的信號(hào)。那么Linux信號(hào)和Qt信息有什么不同?
在 Qt 中,用戶和控件的每次交互過(guò)程稱為?個(gè)事件。比如 "用戶點(diǎn)擊按鈕" 是?個(gè)事件,"用戶關(guān) 閉窗口" 也是?個(gè)事件。每個(gè)事件都會(huì)發(fā)出?個(gè)信號(hào),例如用戶點(diǎn)擊按鈕會(huì)發(fā)出 "按鈕被點(diǎn)擊" 的信 號(hào),用戶關(guān)閉窗口會(huì)發(fā)出 "窗口被關(guān)閉" 的信號(hào)。
Qt信號(hào)同樣包含三個(gè)要素:
由哪個(gè)控件發(fā)出。信號(hào)的類型,如點(diǎn)擊按鈕信號(hào),移動(dòng)輸入框光標(biāo)信號(hào)等等。信號(hào)的處理方式:槽(slot),即函數(shù)。
槽函數(shù),就是對(duì)信號(hào)進(jìn)行響應(yīng)的函數(shù),將信號(hào)與對(duì)應(yīng)的槽函數(shù)關(guān)聯(lián)之后,只要信號(hào)發(fā)出,就能執(zhí)行對(duì)應(yīng)的槽函數(shù)功能。
二.connect關(guān)聯(lián)
在Qt中,想要將信號(hào)和槽函數(shù)關(guān)聯(lián)起來(lái),可以使用函數(shù)connect。
connect(const QObject *sender,
? ? ? ? ? ? ? ?const char *signal,
? ? ? ? ? ? ? ?const QObject *receiver,
? ? ? ? ? ? ? ?const char *method,
? ? ? ? ? ? ? ?Qt::ConnectionType type = Qt::AutoConnection);
sender:信號(hào)的發(fā)送者;
signal:發(fā)送的信號(hào)(信號(hào)函數(shù));
receiver:信號(hào)的接收者;
method:接收信號(hào)的槽函數(shù);
type: 用于指定關(guān)聯(lián)方式,默認(rèn)關(guān)聯(lián)方式為 Qt::AutoConnection,通常不需要手動(dòng)設(shè)定。
disconnect()函數(shù)可以斷開(kāi)信號(hào)和槽的連接,參數(shù)與connect一致。
下面我們?cè)O(shè)計(jì)一個(gè)界面,界面上存在一個(gè)關(guān)閉按鈕,點(diǎn)擊按鈕即可關(guān)閉界面:
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QPushButton *myButten = new QPushButton(this);
myButten->setText("關(guān)閉");
myButten->move(200,200);
connect(myButten,&QPushButton::clicked,this,&Widget::close);
}
分析這段代碼,QPushButten為按鈕類,隨后為其命名為“關(guān)閉”,并設(shè)置其在界面中的位置。
在connect函數(shù)中,定義的按鈕myButten為信號(hào)的發(fā)送者,clicked為信號(hào)函數(shù),即“按鈕被按下”這個(gè)信號(hào),this為信號(hào)的執(zhí)行者,即Widget對(duì)象,也就是界面本身,close為接收到信號(hào)后要執(zhí)行的槽函數(shù),即關(guān)閉界面。
運(yùn)行程序,點(diǎn)擊關(guān)閉即可關(guān)閉界面。
這里擴(kuò)展一點(diǎn)知識(shí):
實(shí)際上上述所給出的connect函數(shù)的參數(shù),是老版本的Qt中的connect函數(shù),能夠看到參數(shù)2和參數(shù)4,是兩個(gè)char* 類型的函數(shù)指針,但實(shí)際上所傳入的函數(shù)指針,并不一定都是char*類型,在老版本中,需要通過(guò)宏來(lái)修改兩個(gè)參數(shù)的類型,這樣太過(guò)麻煩,所以在Qt5版本之后,將connect的參數(shù)改為了模版類型,并且?guī)в辛艘欢ǖ膮?shù)檢查功能,即參數(shù)2和參數(shù)4必須分別是參數(shù)1和參數(shù)3兩個(gè)對(duì)象的成員函數(shù),否則就會(huì)編譯出錯(cuò)。
三.自定義信號(hào)和槽
在上述操作中,我們所使用的信號(hào)函數(shù)和槽函數(shù),都是對(duì)應(yīng)的控件中所自帶的,但是自帶的這些信號(hào)和槽,肯定不能滿足我們所有的需求,所以我們還需要進(jìn)行自定義。
1.自定義槽函數(shù)
槽函數(shù)的本質(zhì),還是類中的一個(gè)成員函數(shù)。
(1)代碼方式
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QPushButton *myButten = new QPushButton(this);
myButten->setText("按鈕");
myButten->move(200,200);
connect(myButten,&QPushButton::clicked,this,&Widget::handleClick);
}
void Widget::handleClick()
{
this->setWindowTitle("按鈕被按下!");
}
注意成員函數(shù)必須要在.h文件中先進(jìn)行聲明。
這里我們編寫(xiě)了一個(gè)名為handleClick的成員函數(shù),并由connect進(jìn)行連接,代碼的含義為:點(diǎn)擊按鈕就會(huì)修改界面的標(biāo)題為“按鈕被按下!”,結(jié)果如下:
(2)界面操作
我們?cè)诮缑嬖O(shè)計(jì)中設(shè)計(jì)一個(gè)按鈕,然后右鍵點(diǎn)擊,能夠看到一個(gè)“轉(zhuǎn)為槽”的選項(xiàng),點(diǎn)擊,就能得到當(dāng)前的QPushButten控件,及其父控件的所有的信號(hào)函數(shù):
我們選擇clicked信號(hào),點(diǎn)擊OK,隨后就會(huì)跳轉(zhuǎn)到.cpp文件,并創(chuàng)建一個(gè)對(duì)應(yīng)的函數(shù),同時(shí)該函數(shù)也會(huì)在.h文件中進(jìn)行聲明:
隨后就可以在該函數(shù)中進(jìn)行代碼編寫(xiě):
void Widget::on_pushButton_clicked()
{
this->setWindowTitle("按鈕已經(jīng)按下");
}
?運(yùn)行代碼,結(jié)果如下:
?能夠看出,通過(guò)界面設(shè)計(jì)的槽函數(shù),不需要使用connect函數(shù)進(jìn)行連接,也可以直接實(shí)現(xiàn)槽函數(shù)對(duì)信號(hào)的響應(yīng)。
這與槽函數(shù)的名字有關(guān),這樣一個(gè)規(guī)則的名字命名方式,Qt就能自動(dòng)把信號(hào)和槽函數(shù)建立聯(lián)系。
on_pushButton_clicked
2.自定義信號(hào)
自定義信號(hào)比較少見(jiàn),在實(shí)際開(kāi)發(fā)中很少會(huì)需要自定義信號(hào),因?yàn)樵贕UI中,用戶能夠進(jìn)行的操作,是可以窮舉的,Qt內(nèi)置的信號(hào),基本上已經(jīng)覆蓋到了所有可能得用戶操作。
信號(hào)是一類非常特殊的函數(shù),定義自定義信號(hào)函數(shù)時(shí),我們只需給出函數(shù)聲明即可,信號(hào)函數(shù)的返回值必須是void,有沒(méi)有參數(shù)都可以。
此時(shí),我們需要告訴Qt,這是一個(gè)“信號(hào)”,通過(guò)在類中使用signals關(guān)鍵字,當(dāng)代碼掃描到該關(guān)鍵字時(shí),就會(huì)自動(dòng)把下面的函數(shù)認(rèn)為是信號(hào),隨后給這些函數(shù)自動(dòng)生成函數(shù)定義。
Qt內(nèi)置的信號(hào),都不需要我們手動(dòng)通過(guò)代碼來(lái)觸發(fā),那么自定義出的信號(hào),該如何觸發(fā)呢?
通過(guò)emit關(guān)鍵字 + 信號(hào)函數(shù),可以觸發(fā)自定義信號(hào),當(dāng)然直接調(diào)用信號(hào)函數(shù),也可以觸發(fā)信號(hào)。
signals:
void mySignal();
public:
void handleMySignal();
在類中聲明信號(hào)。
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
connect(this,&Widget::mySignal,this,&Widget::handleMySignal);
emit mySignal();
//mySignal();
}
void Widget::handleMySignal()
{
this->setWindowTitle("觸發(fā)自定義信號(hào)");
}
隨后進(jìn)行連接并觸發(fā)信號(hào),結(jié)果如下:
3.信號(hào)和槽傳參
我們?cè)谑褂眯盘?hào)時(shí),也可以設(shè)置參數(shù),當(dāng)信號(hào)設(shè)置參數(shù)之后,對(duì)應(yīng)連接的槽函數(shù)也必須擁有相同的類型的參數(shù),參數(shù)的個(gè)數(shù)可以不一致,但信號(hào)的參數(shù)必須比槽函數(shù)的個(gè)數(shù)多。
信號(hào)傳參,本質(zhì)是將參數(shù)的內(nèi)容傳遞給槽函數(shù),從而槽函數(shù)就可以使用參數(shù)內(nèi)容:
signals:
void mySignal(const QString& text);
public:
void handleMySignal(const QString& text);
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
connect(this,&Widget::mySignal,this,&Widget::handleMySignal);
emit mySignal("信號(hào)傳參");
}
void Widget::handleMySignal(const QString& text)
{
this->setWindowTitle(text);
}
結(jié)果如下:
柚子快報(bào)邀請(qǐng)碼778899分享:Qt——信號(hào)和槽
好文鏈接
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。