南昌專(zhuān)業(yè)做網(wǎng)站公司seminar是什么意思
目錄
概述
Q_OBJECT?
自定義信號(hào)
自定義槽
帶參數(shù)的信號(hào)和槽
信號(hào)與槽斷開(kāi)
定義槽函數(shù)時(shí),使用lambda表達(dá)式
概述
所謂的信號(hào)槽,要解決的問(wèn)題,就是響應(yīng)用戶(hù)的操作,這是QT與其他GUI開(kāi)發(fā)框架比較不同的地方。其他的GUI開(kāi)發(fā)框架,搞的方式都要更簡(jiǎn)潔一些,例如網(wǎng)頁(yè)開(kāi)發(fā)中響應(yīng)用戶(hù)操作,主要就是掛回調(diào)函數(shù),不需要搞一個(gè)單獨(dú)的connect完成上述的信號(hào)槽連接。
Qt信號(hào)槽的connect這個(gè)機(jī)制,主要目的是有:
- 解耦合,把觸發(fā)用戶(hù)操作的控件 和 處理對(duì)應(yīng)用戶(hù)的操作邏輯 解耦合
- ”多對(duì)多“ 效果,一個(gè)信號(hào),可以connect到多個(gè)槽函數(shù)上,一個(gè)槽函數(shù),也可以被多個(gè)信號(hào)connect
這里的多對(duì)多,可以與mysql中的多對(duì)多結(jié)合理解
一個(gè)學(xué)生,可以選擇多門(mén)課程來(lái)學(xué)習(xí)
一門(mén)課程,可以被多個(gè)同學(xué)來(lái)選擇
一個(gè)信號(hào),可以connect到多個(gè)槽函數(shù)上
一個(gè)槽函數(shù),可以被多個(gè)信號(hào)connnect
?可以說(shuō) Qt引入信號(hào)槽的機(jī)制,最本質(zhì)的目的就是為了能夠讓信號(hào)和槽之間按照“多對(duì)多”的方式來(lái)進(jìn)行關(guān)聯(lián)。其他的GUI框架往往也不具備這樣的特性。但是在實(shí)際開(kāi)發(fā)中很少用到,絕大部分情況下,一對(duì)一就夠用了
Q_OBJECT?
?Qt中如果要讓某個(gè)類(lèi)能夠使用信號(hào)槽(可以在類(lèi)中定義信號(hào)和槽函數(shù))則必須要在類(lèi)最開(kāi)始的地方,寫(xiě)下Q_OBJECT宏
自定義信號(hào)
Qt中也允許自定義信號(hào),自定義信號(hào)比較少見(jiàn),實(shí)際開(kāi)發(fā)中很少需要自定義信號(hào),信號(hào)對(duì)應(yīng)到用戶(hù)的某個(gè)操作,在GUI,用戶(hù)能夠進(jìn)行哪些操作,是可以窮舉的,Qt內(nèi)置的信號(hào),基本上已經(jīng)覆蓋到了上述所有可能的用戶(hù)操作。
- 信號(hào)是一類(lèi)非常特殊的函數(shù),程序員只要寫(xiě)出函數(shù)聲明,并且告訴Qt,這是一個(gè)”信號(hào)即可“,這個(gè)函數(shù)的定義,是Qt在編譯過(guò)程中,自動(dòng)生成的,程序員無(wú)法干預(yù)。
- 信號(hào)在Qt中是特殊的機(jī)制,Qt生成的信號(hào)函數(shù)的實(shí)現(xiàn),要配合Qt框架做很多既定的操作。
- 作為信號(hào)函數(shù),這個(gè)函數(shù)的返回值,必須是void,有沒(méi)有參數(shù)都可以,甚至也可以支持重載
代碼實(shí)例:
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();
signals:void mySignal();
public:void handleMySignal();
private:Ui::Widget *ui;
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//這里只是建立鏈接,并未發(fā)出信號(hào)connect(this,&Widget::mySignal,this,&Widget::handleMySignal);//發(fā)出自定義的信號(hào)emit mySignal();
}Widget::~Widget()
{delete ui;
}void Widget::handleMySignal()
{this->setWindowTitle("123");
}
自定義槽
自定義槽函數(shù)是非常關(guān)鍵的,開(kāi)發(fā)中大部分情況都是需要自定義槽函數(shù)的,槽函數(shù)就是用戶(hù)觸發(fā)某個(gè)操作后,要進(jìn)行的業(yè)務(wù)邏輯
所謂的slot就是一個(gè)普通的成員函數(shù),自定義一個(gè)槽函數(shù),操作過(guò)程和自定義一個(gè)普通的成員函數(shù)一樣。
另一種自定義槽函數(shù)的方式是 在圖形化界面中右鍵 轉(zhuǎn)到槽
隨后跳轉(zhuǎn)的窗口就是 QPushButton給我們提供的所有的信號(hào)(還包含了QPushButton 父類(lèi)的信號(hào))
在Qt中,除了通過(guò)connect來(lái)連接信號(hào)槽之外,還可以通過(guò)函數(shù)名字的方式來(lái)自動(dòng)連接
如果我們通過(guò)圖形化界面創(chuàng)建控件,還是推薦使用這種快速的方式來(lái)連接信號(hào)槽
如果我們是通過(guò)代碼的方式來(lái)創(chuàng)建控件,還是得手動(dòng)connect(因?yàn)槲覀兊拇a中沒(méi)有調(diào)用connectSlotByName)
帶參數(shù)的信號(hào)和槽
當(dāng)信號(hào)帶有參數(shù)的時(shí)候,槽的參數(shù)必須和信號(hào)的參數(shù)一致,此時(shí)發(fā)射信號(hào)的時(shí)候,就可以給信號(hào)函數(shù)傳遞實(shí)參,與之對(duì)應(yīng)的這個(gè)參數(shù)就會(huì)傳遞到對(duì)應(yīng)的槽函數(shù)中。
這里的參數(shù)一致主要是要求類(lèi)型,個(gè)數(shù)如果不一致也可以,不一致的時(shí)候,要求信號(hào)的參數(shù)的個(gè)數(shù)必須要比槽的參數(shù)個(gè)數(shù)要更多。
如果我們嚴(yán)格要求參數(shù)個(gè)數(shù)一致,就意味著信號(hào)綁定到槽的要求就變高了,換而言之,當(dāng)下這樣的規(guī)則就允許信號(hào)和槽之間綁定更靈活了,更多的信號(hào)可以綁定到這個(gè)槽函數(shù)上了
信號(hào)與槽斷開(kāi)
使用 disconnect 來(lái)斷開(kāi)信號(hào)槽的連接,disconnect使用的方式和connect是非常類(lèi)似的。?
disconnect用的比較少,大部分的情況下,把信號(hào)和槽連上之后,就不必管了,主動(dòng)斷開(kāi)往往是把信號(hào)重新綁定到另一個(gè)槽函數(shù)上。
定義槽函數(shù)時(shí),使用lambda表達(dá)式
代碼示例:
QPushButton* button = new QPushButton(this);button->setText("按鈕");button->move(200,200);connect(button,&QPushButton::clicked,this,[](){qDebug()<<"lambda被執(zhí)行了";})
?lambda表達(dá)式是一個(gè)回調(diào)函數(shù),這個(gè)函數(shù)是無(wú)法直接獲取到上層作用域中的變量,lambda為了解決這個(gè)問(wèn)題,引入了“變量捕獲”語(yǔ)法,通過(guò)變量捕獲,獲取到外層作用域中的變量
connect(button,&QPushButton::clicked,this,[button,this](){qDebug()<<"lambda被執(zhí)行了";button->move(300,300);this->move(100,100);});
如果?當(dāng)前l(fā)ambda里面想使用更多的外層變量,我們可以寫(xiě)作 [=] ,這個(gè)寫(xiě)法的含義就是把上層作用域中的所有變量名都給捕獲進(jìn)來(lái)。
lambda除了可以按照 值的方式來(lái)捕獲變量 [=] 還可以按照引用的方式來(lái)捕獲 [&](Qt中很少這么寫(xiě))捕獲到的變量一般就是各種控件的指針,指針變量按照值傳遞或者引用來(lái)傳遞,都無(wú)所謂。
需要注意的是 lambda語(yǔ)法是C++11中引入的,對(duì)于Qt 5及其更高版本,默認(rèn)就是按照C++ 11來(lái)編譯的,如果使用Qt 4 或者更老的版本,就需要手動(dòng)在 .pro 文件中加上C++11 的編譯選項(xiàng),如下:
CONFIG += c++11?