當前位置:首頁 > 芯聞號 > 充電吧
[導讀]用C++11綁定信號和槽,能使代碼可讀性更高,靈活性更強 注:connect()中可聲明連接類型,默認缺省為AutoConnection 點擊滾動到 “連接類型” 介紹↓ :#include#incl



用C++11綁定信號和槽,能使代碼可讀性更高,靈活性更強
注:connect()中可聲明連接類型,默認缺省為AutoConnection
點擊滾動到 “連接類型” 介紹↓







:

#include#includeclass?MyWindow?:?public?QWidget
{
????Q_OBJECT

public:

????typedef??std::functionfuc1;
????MyWindow(QWidget?*parent?=?0);
????~MyWindow();
????QPushButton?*??btn;
????QLabel*?label;??QVBoxLayout*?Vbox;?
????QGridLayout*?grid;
????void?click2(bool?checked);
????void?set(QString?s);


public?slots:
????void?On_TestBtn_Cliked();
????void?set2(QString?s);


};
MyWindow::MyWindow(QWidget?*parent)
????:?QWidget(parent)
{



????label?=?new?QLabel(QStringLiteral("你好"));?
????btn??=?new?QPushButton("Test");?

????grid?=?new?QGridLayout();?
????grid->addWidget(btn,0,0);

????Vbox?=?new?QVBoxLayout();
????Vbox->addLayout(grid);

????Vbox->addWidget(label);
????setLayout(Vbox);


????fuc1?fu?=?std::bind(&MyWindow::click2,?this,?std::placeholders::_1);
????connect(btn,?&QPushButton::clicked,?this,?fu);


}

MyWindow::~MyWindow()
{

}

void?MyWindow::set(QString?s)
{
????qDebug()?<<"set:"<<?QThread::currentThreadId();
????label->setText(s);
}
void?MyWindow::set2(QString?s)
{
????qDebug()?<<?"set:"?<<?QThread::currentThreadId();
????label->setText(s);
}
void?MyWindow::click2(bool?checked)
{
????qDebug()?<<?"clcik2:"<start();
}
void?MyWindow::On_TestBtn_Cliked()
{

????qDebug()?<<?"click";
}

線程:

#pragma?once
#include#includeclass?MyThread?:
????public?QThread
{
????Q_OBJECT
public:
????QObject*??window;
????void?run();
????MyThread(QObject*?parent=NULL);

????~MyThread();
signals:
????void??print(QString);
};
#include?"MyThread.h"
#include?"MainWindow.h"

MyThread::MyThread(QObject*?parent):QThread(parent)
{
????window?=?parent;
????MyWindow*??w?=?(MyWindow*)parent;?
?std::functionfu?=?std::bind(&MyWindow::set,?w,?std::placeholders::_1);
????connect(this,?&MyThread::print,?w,fu);?
}


MyThread::~MyThread()
{
}


void??MyThread::run()
{
????qDebug()?<<?"Thread?Begin";
????int?cout?=?0;
????while?(true)
????{
????????qDebug()?<<?"MyThread::run:"?<<?QThread::currentThreadId();
????????emit?print(QString::number(cout));
????????Sleep(1);
????????cout++;
????}
}

可以看到,print綁定的線程id和主線程相同,為線程安全

????connect(this,?&MyThread::print,?w,?[=](QString?s)?{

????????w->set(s);
????????qDebug()?<<?"connet?fuc:"?<<?s?<<?"?"?<<?QThread::currentThreadId();
????????//此時?線程id為主線程,可隨意調(diào)用主線程對象的界面操作
????});














void??MyThread::run()
{
????qDebug()?<<?"Thread?Begin";
????int?cout?=?0;
????while?(true)
????{
????????qDebug()?<<?"MyThread::run:"?<<?QThread::currentThreadId();
??????QMetaObject::invokeMethod(w,?"set2",?Q_ARG(QString,?QString::number(cout)));
????????Sleep(1);
????????cout++;
????}
}








MyThread::MyThread(QObject*?parent):QThread(parent)
{
????window?=?parent;
????MyWindow*??w?=?(MyWindow*)parent;

????connect(this,?&MyThread::print,?w,?std::bind(&QLabel::setText,?w->label?,?std::placeholders::_1));
}







connect(this,?&MyThread::print,?w->label,?[=](QString?s)
????{
????????//if(s.indexOf(xxxxx))?此處可以對字符串進行過濾
????????qDebug()?<<?"Bind?Fuc:"?<<?QThread::currentThreadId();
????????w->label->setText(s);
????});

或者

????connect(this,?&MyThread::print,?w,?[=](QString?s)
????{
????????//if(s.indexOf(xxxxx))?此處可以對字符串進行過濾
????????qDebug()?<<?"Bind?Fuc:"?<<?QThread::currentThreadId();
????????w->label->setText(s);
????});









QMetaObject::invokeMethod

修改界面中的槽set2為:

void?MyWindow::set2(QString?s,?int?pid)
{
????if?(pid?==(int)QThread::currentThreadId())
????{
????????qDebug()?<<?QStringLiteral("?此類型的線程不在主線程中::"?)<<?s;
????????qDebug()?<<?"id_1:"?<<?pid?<<?"?id_2:"?<<?QThread::currentThreadId();
????}


}

線程:

void??MyThread::run()
{
????qDebug()?<<?"Thread?Begin";
????int?cout?=?0;
????int?_pid;
????while?(true)
????{
????????_pid?=?(int)QThread::currentThreadId();
????????qDebug()?<<?"MyThread::run:"?<<?_pid;
???????//?emit?print(QString::number(cout));

????????MyWindow*??w?=?(MyWindow*)window;
????????QMetaObject::invokeMethod(w,?"set2",?Qt::ConnectionType::QueuedConnection,
????????????Q_ARG(QString,?"QueuedConnection"),?Q_ARG(int,?_pid)
????????);
????????QMetaObject::invokeMethod(w,?"set2",?Qt::ConnectionType::AutoConnection,
????????????Q_ARG(QString,"AutoConnection"),?Q_ARG(int,?_pid)
????????);
????????QMetaObject::invokeMethod(w,?"set2",?Qt::ConnectionType::BlockingQueuedConnection,?
????????????Q_ARG(QString,?"BlockingQueuedConnection"),Q_ARG(int,?_pid)
????????);
????????QMetaObject::invokeMethod(w,?"set2",?Qt::ConnectionType::DirectConnection,
????????????Q_ARG(QString,?"DirectConnection"),?Q_ARG(int,?_pid)
????????);
????????QMetaObject::invokeMethod(w,?"set2",?Qt::ConnectionType::UniqueConnection,?
????????????Q_ARG(QString,?"UniqueConnection"),?Q_ARG(int,?_pid)
????????);
????????Sleep(1);
????????cout++;
????}
}

可見,DirectConnection連接類型的線程ID與主線程不同,與線程相同,不是線程安全,其他連接類型暫時無法找到方法測試,有例子的朋友可以跟我交流下,謝謝








是官方說明的連接類型,翻譯

說明:信號:發(fā)送者 ?槽:接受者 ?信號和槽所在的線程是創(chuàng)建他們的線程,而不是調(diào)用connnet的時候所在的線程 AutoConnection

如果接收方住在線程發(fā)出信號,使用Qt::DirectConnection。否則,使用Qt::QueuedConnection。連接類型發(fā)送信號時決定。
解釋:
如果接收方住在線程發(fā)出信號,使用Qt::DirectConnection。否則,使用Qt::QueuedConnection。連接類型發(fā)送信號時決定。
也就是說,自動判斷,如果信號和槽在同一個線程,就調(diào)用Qt::DirectConnection,否則調(diào)用Qt::QueuedConnection

DirectConnection

調(diào)用插槽立即發(fā)出信號時。槽是在信號線程中執(zhí)行的。

QueuedConnection

可以理解為異步?
當槽發(fā)送給調(diào)用接收事件循環(huán)的線程時,槽在接收者的線程中執(zhí)行。
也就是說,此連接類型,只管把信號發(fā)送到槽所在的線程事件中,不會等待槽所在的線程事件處理完畢
,槽所在線程事件循環(huán)當處理到此信號時,才會執(zhí)行相應(yīng)操作

BlockingQueuedConnection

可以理解為同步,阻塞當前線程直到同步?
當槽發(fā)送給調(diào)用接收事件循環(huán)的線程時,槽在接收者的線程中執(zhí)行。
也就是說,此連接類型,不但把信號發(fā)送到槽所在的線程事件中,而且會等待槽所在的線程事件處理完畢
,槽所在線程事件循環(huán)當處理到此信號時,才會執(zhí)行相應(yīng)操作,信號所在的線程才會繼續(xù)下一行代碼

UniqueConnection

資料太少,不知道此類型的大概用途。。。
這是一個標志,可以結(jié)合上述任何一個連接類型,使用逐位或。當Qt:UniqueConnection,QObject:connect()將會失敗如果連接已經(jīng)存在(即如果相同的信號已經(jīng)連接到同一個槽同一雙對象)。這個標志是在Qt 4.6中引入的。

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉