石家莊網(wǎng)站建站公司百度廣告位價格
1.QT信號槽主要分兩個連接方式,手動和自動:
1.1 使用 connect() 函數(shù)手動連接信號和槽:
QObject::connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));
自動:
1.2 使用 lambda 表達(dá)式連接信號和槽:
connect(sender, &Sender::signal, ={
receiver->slot();
});
1.3 通過使用 QMetaObject::connectSlotsByName() 函數(shù)自動將部件中以 on_ 開頭命名的槽函數(shù)與其對應(yīng)的信號相連接。例如,在設(shè)計窗口中選擇一個按鈕,并在屬性編輯器中設(shè)置其 objectName 屬性為 “myButton”,然后定義一個 on_myButton_clicked() 槽函數(shù),該函數(shù)將自動連接到該按鈕的 clicked() 信號上。
2.connect()函數(shù)的五種連接方式,一次連接,終身調(diào)用,除非disconnect。
enum ConnectionType {AutoConnection,//默認(rèn)DirectConnection,//立即調(diào)用QueuedConnection,//放在接收者隊列BlockingQueuedConnection,//與放在接收者隊列,同時阻塞發(fā)送者UniqueConnection = 0x80//標(biāo)志位,避免重復(fù)鏈接
};
connect()函數(shù)原型如下:
[static] QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection)
2.1 Qt::AutoConnection(默認(rèn))
根據(jù) sender 和 receiver 兩者所在線程,當(dāng)信號發(fā)出時作出判斷。同一線程則 Qt::DirectConnection 連接,否則使用 Qt::QueuedConnection 連接。容易產(chǎn)生誤區(qū)的點:不是sender的所屬線程,而是真正觸發(fā)了emit 信號的動作線程。
Qt::DirectConnection
無論sender和receiver是否在同一線程,都會立刻調(diào)用槽函數(shù),最簡單的理解成把一段代碼“臨時插入”到了運行棧,所以在多線程情況下非常危險,必須做好線程同步。
Qt::QueuedConnection
sender的信號會被壓入到接收者的事件循環(huán)中,所以不會立即調(diào)用。而是等到當(dāng)接收者對象處理其自身的消息隊列時,再針對消息隊列中的這個信號進(jìn)行處理??梢哉f就是為了開發(fā)者解決跨線程通信而設(shè)計的。當(dāng)然你也可以用于同一個線程不同對象,這種相同線程的強(qiáng)行指定隊列方式通常都會和GUI的模態(tài)窗有關(guān)。
Qt::BlockingQueuedConnection
Blocking+QueuedConnection,他的槽函數(shù)運行時機(jī)與QueuedConnection是一致的。那Blocking的意義是什么?就是阻塞發(fā)送者!直到槽函數(shù)運行完畢再繼續(xù)執(zhí)行。源碼上相比QueuedConnection的實現(xiàn)多加了一個等待輸入的信號量QSemaphore,所以一旦接收者和發(fā)送者在同一線程,那就會發(fā)生死鎖。
Qt::UniqueConnection
這個其實嚴(yán)格上來說相比上面四種方式并不算新的連接方式,而是用于修飾上面的四種連接方式。他實現(xiàn)的效果就是避免重復(fù)連接,因為Qt的信號槽是可以同一個信號和槽函數(shù)重復(fù)多次連接。這種通常都會是只執(zhí)行一次就好,那就通過這個標(biāo)志位進(jìn)行修飾,達(dá)到多次連接(實際上也只是連接了一次)也只調(diào)用一次槽函數(shù)的效果。用(Qt::ConnectionType|Qt::UniqueConnection)來修飾。
connect(ui->btn_close, &QPushButton::clicked, this, &QWidget::close,Qt::DirectConnection|Qt::UniqueConnection)