1. 程式人生 > >關於QObject::connect中函式引數

關於QObject::connect中函式引數

1: 首先要連結的兩個類必須繼承與QObject,同時新增 Q_OBJECT;

2:在qt中QObject::connect中填寫的signal和slot函式,一定要填寫引數型別;

因為類中的函式可以,也就是,過載函式名一樣,引數不一樣,如果QObject::connect中的函式沒有引數型別,則無法正確連線;

3: QObject::connect中的signal 和 slot 函式一定要有引數型別, 但是,不可以有引數:

You must use the SIGNAL() and SLOT() macros when specifying the signal and the method, for example:


QLabel *label = new QLabel;
QScrollBar *scrollBar = new QScrollBar;
QObject::connect(scrollBar, SIGNAL(valueChanged(int

)),      label,  SLOT(setNum(int)));
This example ensures that the label always displays the current scroll bar value. Note that the signal and slots parameters must not contain any variable names, only the type. E.g. the following would not work and return false:


// WRONG
QObject::connect(scrollBar, SIGNAL(valueChanged(int value
)),  label, SLOT(setNum(int value)));

4:在引數部分,如定義了:typedef unsigned char       BYTE;

//signal:

void  CClass1::setBuf( BYTE * );

//pulic slots:

void CClass2::setBuf(  unsigned char * )

{

    MessageBoxQ( "訊息響應" );

}

這樣,通常可以用BYTE替換unsigned char ;

但是在QObject::connect(  pClass1, SIGNAL( setBuf( BYTE * )  ),  pClass2, SLOT( setBuf( unsigned char * ) )  );

編譯時不會有問題的,但是訊息無法響應,

修改方法:

void CClass2::setBuf(  unsigned char * ) 為 void CClass2::setBuf(  BYTE*  )

QObject::connect(  pClass1, SIGNAL( setBuf( BYTE * )  ),  pClass2, SLOT( setBuf( BYTE * ) )  );

可能錯誤的原因:

SIGNAL 和 SLOT是將其內容轉為字串,

所以,如果訊息傳遞前 函式和引數 是按照字串嚴格比較話,那麼 “BYTE” 和“unsigned char” 就不同了;

具體原因需要分析原始碼;

5: 關於  QObject::connect函式宣告: QMetaObject::Connectionconnect(const QObject * sender, const char * signal, const QObject * receiver, const char * method, Qt::ConnectionType type = Qt::AutoConnection)

從這裡可以看出: 最後一個引數是設定連線型別,預設引數是Qt::AutoConnection;

Qt::ConnectionType描述:

enum Qt::ConnectionType
This enum describes the types of connection that can be used between signals and slots. In particular, it determines whether a particular signal is delivered to a slot immediately or queued for delivery at a later time.


Constant                   Value                 Description
Qt::AutoConnection    0                  (default) If the signal is emitted from a different thread than the receiving object, the signal is queued, behaving as Qt::QueuedConnection. Otherwise, the slot is invoked directly, behaving as Qt::DirectConnection. The type of connection is determined when the signal is emitted.
Qt::DirectConnection   1                       The slot is invoked immediately, when the signal is emitted.
Qt::QueuedConnection 2                          The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread.
Qt::BlockingQueuedConnection3Same as QueuedConnection, except the current thread blocks until the slot returns. This connection type should only be used where the emitter and receiver are in different threads.

這裡注意:Qt::BlockingQueuedConnection 用於“執行緒間”阻塞執行;

如果線上程間用Qt::DirectConnection,(Qt::DirectConnection 使用在同一執行緒中連結作為引數) 雖然會阻塞執行,但是slot函式中如果有UI類的話會提示錯誤;

如果為預設函式引數,觸發訊息後,立即執行後面的程式碼,然後某一時刻再執行slot函式,這樣非常不穩定,不安全;

當然還是要根據具體需求設定引數;

6:connect中的常量引數,引用引數,一般引數;

1:  SIGNAL函式, 常量引用引數, SLOT函式的引數一般連結也應該是常量引用引數;如:

signals:
void resultReady( const QString & s);

public slots:

void slot_string( const QString & str )
{
// str = "123";
qDebug()<<str;
}

connect( this, SIGNAL(resultReady(const QString&)), this, SLOT(slot_string(const QString&)) , Qt::DirectConnection);

因為上述是const引數,所以slot中無法修改引數資料;如果想修改資料有兩個方法:

(1): 賦值一個新的變數應用;

(2): 修改slot函式引數:

void slot_string( QString str )
{
str = "123";
qDebug()<<str;
}

connect( this, SIGNAL(resultReady(const QString&)), this, SLOT(slot_string(QString)) , Qt::DirectConnection);

注:大部分的Qt的SIGNAL函式都是常量引用引數;

2: SIGNAL函式, 引用引數, SLOT函式的引數也可以是 引用引數 或一般引數;

3:SIGNAL函式和SLOT函式都是一般引數;

說明:

1:這裡主要講的是區別就是在connect的時候,SGNAL ,SLOT的引數在引用於非引用對效率的影響和引數資料的修改;

2:線上程間引數傳遞的時候,SGNAL和SLOT位於兩個不同的執行緒,如果connect的連結型別是Qt::QueuedConnection非阻塞執行,SLOT的引數是一般引數,那麼SLOT函式的引數就是一個數據copy,

線上程emit SGNAL後,如果執行緒中作為從引數的資料丟失或改變,但是SLOT函式用因為有資料備份,所以SLOT函式中的引數資料不會受到影響;

7:關於connect函式:

connect函式後多種過載方法,常用的有:

1:QMetaObject::Connection QObject::connect(const QObject * sender, const char * signal, const QObject * receiver, const char * method, Qt::ConnectionType type = Qt::AutoConnection) [static]

for example:


QLabel *label = new QLabel;
QScrollBar *scrollBar = new QScrollBar;
QObject::connect( scrollBar, SIGNAL(valueChanged(int)),     label,  SLOT(setNum(int)) );

2:

QMetaObject::Connection QObject::connect(const QObject * sender, PointerToMemberFunction signal, const QObject * receiver, PointerToMemberFunction method, Qt::ConnectionType type) [static]

Example:


QLabel *label = new QLabel;
QLineEdit *lineEdit = new QLineEdit;
QObject::connect( lineEdit, &QLineEdit::textChanged,   label,  &QLabel::setText );

說明:

建議用方法2,從應用方便講,

(1):這個方法不需要填寫引數型別;

(2):在上述“第6點”中,不論SIGNAL函式和SLOT函式是引用引數或非引用引數,會自動根據實際情況進行引數傳遞(實參或形參);