1. 程式人生 > >QT使用訊號與槽注意事項

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:

  1. http://doc.qt.io/qt-5.6/qobject.html#connect-2
  2. http://doc.qt.io/qt-5.6/qt.html#ConnectionType-enum

覺得文章對你有幫助,可以用微信掃描二維碼捐贈給博主,謝謝!
微信
如需轉載請標明出處:http://blog.csdn.net/itas109
QQ技術交流群:129518033