深入理解Qt信號槽機(jī)制
1. 信號和槽概述
信號槽是 Qt 框架引以為豪的機(jī)制之一。所謂信號槽,實(shí)際就是觀察者模式(發(fā)布-訂閱模式)。當(dāng)某個(gè)`事件`發(fā)生之后,比如,按鈕檢測到自己被點(diǎn)擊了一下,它就會(huì)發(fā)出一個(gè)信號(signal)。這種發(fā)出是沒有目的的,類似廣播。如果有對象對這個(gè)信號感興趣,它就會(huì)使用連接(connect)函數(shù),意思是,將想要處理的信號和自己的一個(gè)函數(shù)(稱為槽(slot))綁定來處理這個(gè)信號。也就是說,當(dāng)信號發(fā)出時(shí),被連接的槽函數(shù)會(huì)自動(dòng)被回調(diào)。這就類似觀察者模式:當(dāng)發(fā)生了感興趣的事件,某一個(gè)操作就會(huì)被自動(dòng)觸發(fā)。
1.1 信號的本質(zhì)
信號是由于用戶對窗口或控件進(jìn)行了某些操作,導(dǎo)致窗口或控件產(chǎn)生了某個(gè)特定事件,這時(shí)候Qt對應(yīng)的窗口類會(huì)發(fā)出某個(gè)信號,以此對用戶的挑選做出反應(yīng)。
因此根據(jù)上述的描述我們得到一個(gè)結(jié)論:信號的本質(zhì)就是事件,比如:
- 按鈕單擊、雙擊
- 窗口刷新
- 鼠標(biāo)移動(dòng)、鼠標(biāo)按下、鼠標(biāo)釋放
- 鍵盤輸入
那么在Qt中信號是通過什么形式呈現(xiàn)給使用者的呢?
- 我們對哪個(gè)窗口進(jìn)行操作, 哪個(gè)窗口就可以捕捉到這些被觸發(fā)的事件。
- 對于使用者來說觸發(fā)了一個(gè)事件我們就可以得到Qt框架給我們發(fā)出的某個(gè)特定信號。
- 信號的呈現(xiàn)形式就是函數(shù), 也就是說某個(gè)事件產(chǎn)生了, Qt框架就會(huì)調(diào)用某個(gè)對應(yīng)的信號函數(shù), 通知使用者。
在QT中信號的發(fā)出者是某個(gè)實(shí)例化的類對象,對象內(nèi)部可以進(jìn)行相關(guān)事件的檢測。
1.2 槽的本質(zhì)
在Qt中槽函數(shù)是一類特殊的功能的函數(shù)
,在編碼過程中也可以作為類的普通成員函數(shù)來使用
。之所以稱之為槽函數(shù)是因?yàn)樗鼈冞€有一個(gè)職責(zé)就是對Qt框架中產(chǎn)生的信號進(jìn)行處理。
舉個(gè)簡單的例子:
女朋友說:“我肚子餓了!”,于是我?guī)コ燥垺?/p>
上邊例子中相當(dāng)于女朋友發(fā)出了一個(gè)信號, 我收到了信號并其將其處理掉了。
- 女朋友 -> 發(fā)送信號的對象, 信號內(nèi)容: 我餓了
- 我 -> 接收信號的對象并且處理掉了這個(gè)信號, 處理動(dòng)作: 帶她去吃飯
在Qt中槽函數(shù)的所有者也是某個(gè)類的實(shí)例對象。
1.3 信號和槽的關(guān)系
在Qt中信號和槽函數(shù)都是獨(dú)立的個(gè)體,本身沒有任何聯(lián)系,但是由于某種特性需求我們可以將二者連接到一起,相當(dāng)于一個(gè)綁定,在Qt中我們需要使用QOjbect類
中的connect
函數(shù)進(jìn)二者的關(guān)聯(lián)。
QMetaObject::Connection QObject::connect( const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type = Qt::AutoConnection); - 參數(shù): - sender: 發(fā)出信號的對象 - signal: 屬于sender對象, 信號是一個(gè)函數(shù), 這個(gè)參數(shù)的類型是函數(shù)指針, 信號函數(shù)地址 - receiver: 信號接收者 - method: 屬于receiver對象, 當(dāng)檢測到sender發(fā)出了signal信號, receiver對象調(diào)用method方法,信號發(fā)出之后的處理動(dòng)作 // connect函數(shù)相對于做了信號處理動(dòng)作的注冊 // 調(diào)用conenct函數(shù)的sender對象的信號并沒有產(chǎn)生, 因此receiver對象的method也不會(huì)被調(diào)用 // method槽函數(shù)本質(zhì)是一個(gè)回調(diào)函數(shù), 調(diào)用的時(shí)機(jī)是信號產(chǎn)生之后, 調(diào)用是Qt框架來執(zhí)行的 // connect中的sender和recever兩個(gè)指針必須被實(shí)例化了, 否則conenct不會(huì)成功 connect(const QObject *sender, &QObject::signal, const QObject *receiver, &QObject::method);
1.4 通過實(shí)例加深理解
現(xiàn)在要實(shí)現(xiàn)一個(gè)簡單的功能,就說創(chuàng)建一個(gè)按鈕,點(diǎn)擊這個(gè)按鈕關(guān)閉窗口
然后思考,這個(gè)功能的信號發(fā)出者,信號接受者,以及發(fā)出什么信號,接受信號后怎么做
- 按鈕: 信號發(fā)出者 ->
QPushButton
- 窗口: 信號的接收者和處理者 ->
QWidget
- 發(fā)出信號:被點(diǎn)擊 -> clicked
- 槽函數(shù),即如何處理 -> close
現(xiàn)在我們來實(shí)現(xiàn)一下
在ui中添加一個(gè)button,取名為closeBtn
然后再M(fèi)ainwindow.cpp 文件中
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); connect(ui->closeBtn,&QPushButton::clicked,this,&MainWindow::close); } MainWindow::~MainWindow() { delete ui; }
注意這條語句
connect(ui->closeBtn,&QPushButton::clicked,this,&MainWindow::close);
通過這條語句來實(shí)現(xiàn)綁定
現(xiàn)在我們來運(yùn)行一下
點(diǎn)擊按鈕,窗口關(guān)閉
到此這篇關(guān)于深入理解Qt信號槽機(jī)制的文章就介紹到這了,更多相關(guān)Qt信號槽機(jī)制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++中l(wèi)ist的使用方法及常用list操作總結(jié)
這篇文章主要介紹了C++中l(wèi)ist的使用方法及常用list操作總結(jié)的相關(guān)資料,需要的朋友可以參考下2017-06-06C語言堆與二叉樹的順序結(jié)構(gòu)與實(shí)現(xiàn)
堆是計(jì)算機(jī)科學(xué)中一類特殊的數(shù)據(jù)結(jié)構(gòu)的統(tǒng)稱,通常是一個(gè)可以被看做一棵完全二叉樹的數(shù)組對象。而堆排序是利用堆這種數(shù)據(jù)結(jié)構(gòu)所設(shè)計(jì)的一種排序算法。本文將詳細(xì)介紹堆與二叉樹的順序結(jié)構(gòu)與實(shí)現(xiàn),需要的可以參考一下2022-05-05關(guān)于python調(diào)用c++動(dòng)態(tài)庫dll時(shí)的參數(shù)傳遞問題
這篇文章主要介紹了python調(diào)用c++動(dòng)態(tài)庫dll時(shí)的參數(shù)傳遞,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04C語言中求字符串長度的函數(shù)的幾種實(shí)現(xiàn)方法
這篇文章主要介紹了C語言中求字符串長度的函數(shù)的幾種實(shí)現(xiàn)方法,需要的朋友可以參考下2018-08-08