QT使用訊號與槽注意事項
QT使用訊號與槽注意事項
如需轉載請標明出處:http://blog.csdn.net/itas109
QQ技術交流群:129518033
目錄
文章目錄
環境:
QT版本:5.6.2
VS版本:VS2013
系統版本:windows 7 64bit
前言
Qt 訊號槽一直以來都是QT的核心之一。但是,大家真的對訊號的槽非常瞭解嗎?下面介紹的一些內容,你可能並不知道。
1.基本用法
QLabel *label = new QLabel; QLineEdit *lineEdit = new QLineEdit; QObject::connect(lineEdit, &QLineEdit::textChanged,label, &QLabel::setText);
2.slots的函式用法
函式原型:
QMetaObject::Connection QObject::connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
使用:
void someFunction();
QPushButton *button = new QPushButton;
QObject::connect(button, &QPushButton::clicked, someFunction);
3.slots的lambda表示式
QByteArray page = ...; QTcpSocket *socket = new QTcpSocket; socket->connectToHost("qt-project.org", 80); QObject::connect(socket, &QTcpSocket::connected, [=] () {socket->write("GET " + page + "\r\n");});
4.斷開連線到物件訊號的所有Object
disconnect(myObject, 0, 0, 0);
等同於
myObject->disconnect();
5.斷開連線到特定訊號的所有Object
disconnect(myObject, SIGNAL(mySignal()), 0, 0);
等同於
myObject->disconnect(SIGNAL(mySignal()));
6.斷開特定接收者
disconnect(myObject, 0, myReceiver, 0);
等同於
myObject->disconnect(myReceiver);
7.connect函式的第5引數Qt::ConnectionType
引數 | 值 | 說明 |
---|---|---|
Qt::AutoConnection | 0 | (預設)如果接收者位於發出訊號的執行緒中,則使用Qt :: DirectConnection。 否則,使用Qt :: QueuedConnection。 連線型別在發出訊號時確定 |
Qt::DirectConnection | 1 | 發出訊號時立即呼叫插槽。 插槽在訊號執行緒中執行。相當於槽函式直接執行,執行完之後,才繼續執行訊號的後續內容 |
Qt::QueuedConnection | 2 | 槽函式在控制回到接收者所線上程的事件迴圈時被呼叫。 槽函式在接收者的執行緒中執行。傳送訊號之後,槽函式不會立刻被呼叫,等到接收者的當前函式執行完,進入事件迴圈之後,槽函式才會被呼叫 |
Qt::BlockingQueuedConnection | 3 | 與Qt :: QueuedConnection相同,除了訊號執行緒阻塞直到槽返回。 如果接收者與訊號位於同一執行緒中,則不得使用此連線,否則程式將會死鎖 |
Qt::UniqueConnection | 0x80 | 這是一個可以使用按位OR與上述任何一種連線型別組合的標誌。 當設定Qt :: UniqueConnection時,如果連線已經存在,QObject :: connect()將失敗(即,如果相同的訊號已連線到同一對物件的相同插槽)。 這個標誌是在Qt 4.6中引入的 |
這裡需要注意的是一般我們都是採用預設引數Qt::AutoConnection。但是,需要注意有時可能會出現問題。
例如,我們要在登入成功後關閉當前介面。實現如下:
void login()
{
...
//驗證完畢,返回登入成功訊號
emit loginSuccess();
this->hide();
}
如果此時我們採用Qt::AutoConnection,並且訊號與槽位於同一執行緒,那麼QT會自動為我們選擇為Qt::DirectConnection方式。也就是必須等待訊號對應的槽函式執行完,才能執行hide操作。這是如果槽函式是一個耗時操作,那麼就會出現無法hide的情況,這種情況下,我們需要手動設定Qt::QueuedConnection或者將hide函式在emit之前執行。
總結一下就是emit函式之後的內容的執行順序與訊號與槽的連線方式有關。如果需要立即執行emit之後的函式,就需要設定為Qt::QueuedConnection,如果要立即執行槽函式,就需要設定為Qt::QueuedConnection。
8.QObject::connect: Cannot queue arguments of type ‘XXX’
出現這個錯誤是由於對於Qt::QueuedConnection連線,引數必須是Qt的元物件系統已知的型別,因為Qt需要複製引數以將它們儲存在幕後的事件中。
在建立連線之前,請呼叫qRegisterMetaType()註冊資料型別。
9.QTimer的 singleShot
函式原型:
[static] void QTimer::singleShot(int msec, const QObject *receiver, const char *member)
QTimer::singleShot(100,this, &A::function());
QTimer::singleShot(100,[=]{qDebug() << "time out"; });
Reference:
覺得文章對你有幫助,可以用微信掃描二維碼捐贈給博主,謝謝!
如需轉載請標明出處:http://blog.csdn.net/itas109
QQ技術交流群:129518033