【Qt訊號和槽】
來公司不久,當前主要任務就是看書,安排了一些進度,就當是複習和加深印象了,來吧,Qt中的訊號和槽。
這裡順帶說一下,訊號和槽機制 = 觀察者模式
(前兩天看一篇英文文件,看的蛋疼,什麼叫觀察者模式。。。漲姿勢了)
一 、訊號
當物件改變其狀態時,訊號就被該物件emit出去。
在標頭檔案(.h)中 Signal:關鍵字修飾訊號,自己看吧。。。
class Test : public QObject
{
Q_OBJECT
signals:
void Signal();
void Signal(int x);
void Signal(int x, int y);
} ;
二、 槽
槽可以有引數,但槽的引數不能預設(一般來說,訊號的引數就會傳入給槽,Qt底層已經實現了,但是我絕不會去看那些蛋疼的實現程式碼)
public slots:
void Slot();
void Slot(int x);
void Slot(int x, int y);
三 訊號和槽的關聯
通過QObject物件的connect函式來進行關聯,關聯方式如下:
connect(this, signal, this, slot);
//給看個原函式 bool QObject::connect ( const QObject * sender, const char * signal, const QObject * receiver, const char * member ) [static]
看一些例子吧
1.訊號觸發訊號
class TestWidget : public QWidget
{
public:
TestWidget();
...
signals:
void TestSignal();
...
private:
...
QPushButton *TestButton;
};
TestWidget::TestWidget()
{
TestButton = new QPushButton( this );
connect( TestButton, SIGNAL(clicked()), this, SIGNAL(TestSignal()) );
}
必須注意的事情
1.這裡第一點就想說說connect第5個引數
前面4個就不說了,說一下第五個引數;
第五個引數是一個enum Qt::Connection Type型別
一共有6種類型,這裡就說說三種常用的吧。。。
Qt支援6種連線方式,其中3中最主要:
Qt::DirectConnection(直連方式)
當訊號發出後,相應的槽函式將立即被呼叫。emit語句後的程式碼將在所有槽函式執行完畢後被執行。(訊號與槽函式關係類似於函式呼叫,同步執行)
Qt::QueuedConnection(排隊方式)
當訊號發出後,排隊到訊號佇列中,需等到接收物件所屬執行緒的事件迴圈取得控制權時才取得該訊號,呼叫相應的槽函式。emit語句後的程式碼將在發出訊號後立即被執行,無需等待槽函式執行完畢。(此時訊號被塞到訊號佇列裡了,訊號與槽函式關係類似於訊息通訊,非同步執行)
Qt::AutoConnection(自動方式)
Qt的預設連線方式,如果訊號的發出和接收這個訊號的物件同屬一個執行緒,那個工作方式與直連方式相同;否則工作方式與排隊方式相同。
2.就說說訊號和槽的一些不能問題、
1.巨集定義不能用在signal和slot引數中
2.建構函式不能用在signals和slots宣告中(是個正常人也不會這麼做)
3.(重要)訊號與槽不能有預設引數
4.(重要) 函式指標不能為訊號和槽的引數!!!!
但是問題來了,非常傳函式指標怎麼辦?
public slots:
void apply( ApplyFunctionType, char *);
居然是定義別名。。。。