淺談Qt信號與槽的各種連接方式
簡介
信號槽是 Qt 框架引以為豪的機(jī)制之一。當(dāng)用戶觸發(fā)某個(gè)事件時(shí),就會(huì)發(fā)出一個(gè)信號(signal),這種發(fā)出是沒有目的的,類似廣播。如果有對象對這個(gè)信號感興趣,它就會(huì)連接(connect)綁定一個(gè)函數(shù)(稱為槽slot)來處理這個(gè)信號。也就是說當(dāng)信號發(fā)出時(shí),被連接的槽函數(shù)會(huì)自動(dòng)被回調(diào)。這有點(diǎn)類似與開發(fā)模式中的觀察者模式,即當(dāng)發(fā)生了感興趣的事件,某一個(gè)操作就會(huì)被自動(dòng)觸發(fā)
信號和槽是Qt特有的信息傳輸機(jī)制,是Qt設(shè)計(jì)程序的重要基礎(chǔ),它可以讓互不干擾的對象建立一種聯(lián)系。槽的本質(zhì)是類的成員函數(shù),其參數(shù)可以是任意類型的。和普通C++成員函數(shù)幾乎沒有區(qū)別,它可以是虛函數(shù),也可以被重載??梢允枪械摹⒈Wo(hù)的、私有的、也可以被其他C++成員函數(shù)調(diào)用。唯一區(qū)別的是:槽可以與信號連接在一起,每當(dāng)和槽連接的信號被發(fā)射的時(shí)候,就會(huì)調(diào)用這個(gè)槽
連接信號槽 connect 函數(shù)的第五個(gè)參數(shù)
connect 函數(shù)原型如下:
[static] QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection)
ConnectionType 是一個(gè)定義在 Qt namespace 中的一個(gè)枚舉,具體內(nèi)容如下:
enum ConnectionType {
AutoConnection,
DirectConnection,
QueuedConnection,
BlockingQueuedConnection,
UniqueConnection = 0x80
};
- Qt::AutoConnection:默認(rèn)值。根據(jù) sender 和 receiver 所處線程在信號發(fā)出時(shí)作出判斷。如果在同一線程則使用 Qt::DirectConnection 連接,否則使用 Qt :: QueuedConnection 連接。需要注意的是,這個(gè)判斷和 sender 對象所處線程無關(guān),真正判斷的是發(fā)出信號這個(gè)動(dòng)作所在的線程
- Qt::DirectConnection:槽函數(shù)會(huì)在信號發(fā)送的時(shí)候直接被調(diào)用,槽函數(shù)運(yùn)行于信號發(fā)送者所在線程。效果看上去就像是直接在信號發(fā)送位置調(diào)用了槽函數(shù)。需要注意的是,在多線程環(huán)境下比較危險(xiǎn),可能會(huì)造成奔潰
- Qt::QueuedConnection:槽函數(shù)在控制回到接收者所在線程的事件循環(huán)時(shí)被調(diào)用,槽函數(shù)運(yùn)行于信號接收者所在線程。發(fā)送信號之后,槽函數(shù)不會(huì)立刻被調(diào)用,等到接收者的當(dāng)前函數(shù)執(zhí)行完,進(jìn)入事件循環(huán)之后,槽函數(shù)才會(huì)被調(diào)用。多線程環(huán)境下一般用這個(gè)
- Qt::BlockingQueuedConnection:槽函數(shù)的調(diào)用時(shí)機(jī)與 Qt::QueuedConnection 一致,不過發(fā)送完信號后發(fā)送者所在線程會(huì)阻塞,直到槽函數(shù)運(yùn)行完,在多線程間需要同步的場合可能需要這個(gè)。需要注意的是,接收者和發(fā)送者絕對不能在一個(gè)線程,否則程序會(huì)死鎖
- Qt::UniqueConnection:這個(gè) flag 可以通過按位或(|)與以上四個(gè)結(jié)合在一起使用。當(dāng)這個(gè)flag設(shè)置時(shí),當(dāng)某個(gè)信號和槽已經(jīng)連接時(shí),再進(jìn)行重復(fù)的連接就會(huì)失敗,也就是避免了重復(fù)連接
信號與槽的連接方式
C++ 連接信號槽 - Qt4 語法
connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(close()));
C++ 連接信號槽 - Qt5 語法
connect(ui->pushButton, &QPushButton::clicked, this, &MainWindow::close)
C++ 連接信號槽 - 函數(shù)指針
void(MainWindow:: *buttonClickSlot)() = &MainWindow::onButtonPushed; connect(ui->pushButton, &QPushButton::clicked, this, buttonClickSlot);
C++ 連接信號槽 - Lambda 表達(dá)式
connect(ui->pushButton, &QPushButton::clicked, this, [=](){ this->close(); });
C++ 信號連接 QML 的槽
class Test {
signals:
void sendData(QString str);
}
1)如果注冊的是全局對象,則需要使用 Connections 連接:
Connections {
target: test
onSendData: {
console.log(str)
}
}
2)如果注冊的是類,則需要先實(shí)例化對象,之后直接使用 on 接收:
Test {
onSendData: {
console.log(str)
}
}
QML 信號連接 C++ 的槽
#include <QQuickItem>
QObject *quitButton = root->findChild<QObject*>("quitButton");
if (quitButton) {
QObject::connect(quitButton, SIGNAL(clicked()), &app, SLOT(quit()));
}
C++ 調(diào)用 QML 函數(shù)
QObject *changeBtn = root->findChild<QObject*>("objectName");
if (changeBtn)
{
QMetaObject::invokeMethod(changeBtn, "changeColor");
}
QML 調(diào)用 C++ 函數(shù)
onClicked:
{
className.test();
}
QML 信號連接 QML 的槽
// A.qml
Rectangle {
signal sendData(var data)
}
// B.qml
Rectangle {
onSendData: console.log(data)
}
到此這篇關(guān)于淺談Qt信號與槽的各種連接方式的文章就介紹到這了,更多相關(guān)Qt信號與槽連接內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++浮點(diǎn)數(shù)在內(nèi)存中的存儲(chǔ)詳解
大家好,本篇文章主要講的是C++浮點(diǎn)數(shù)在內(nèi)存中的存儲(chǔ)詳解,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下2022-01-01
C++實(shí)現(xiàn)判斷字符串是否回文實(shí)例解析
這篇文章主要介紹了C++實(shí)現(xiàn)判斷字符串是否回文,其中采用了數(shù)據(jù)結(jié)構(gòu)中棧以及過濾字符等技術(shù),,需要的朋友可以參考下2014-07-07
Win32應(yīng)用程序(SDK)設(shè)計(jì)原理詳解
這篇文章主要介紹了Win32應(yīng)用程序(SDK)設(shè)計(jì)原理,對于理解win32應(yīng)用程序運(yùn)行原理有很大的幫助,需要的朋友可以參考下2014-08-08
基于C++詳解數(shù)據(jù)結(jié)構(gòu)(附帶例題)
數(shù)據(jù)結(jié)構(gòu)作為每一個(gè)IT人不可回避的問題,本文基于C++編寫,下面這篇文章主要給大家介紹了關(guān)于數(shù)據(jù)結(jié)構(gòu)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06
Qt實(shí)現(xiàn)FTP的上傳和下載的實(shí)例代碼
本篇文章主要介紹了Qt實(shí)現(xiàn)FTP的上傳和下載的實(shí)例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-07-07
c++ 如何在libuv中實(shí)現(xiàn)tcp服務(wù)器
這篇文章主要介紹了c++ 如何在libuv中實(shí)現(xiàn)tcp服務(wù)器,幫助大家更好的理解和使用libuv,感興趣的朋友可以了解下2021-02-02

