QT信號/槽


在我的理解中,QT和Android都是類似的開發框架,都是由開發團隊封裝了各式各樣的接口和數據結構.將一些問題的解決方法簡單化
比如QT中將線程封裝為QThread,派生類通過重寫run方法來將代碼投入到新的線程執行,而同樣的Android中的線程是Java自帶的Thread類,同樣是重寫run方法來執行線程代碼.
由此可見,一些問題的解決方法是存在共性的.

QT的signals slots connect

在程序中引進信號/槽機制,需要元數據 也就是並非任意的類都能添加信號/槽功能

這樣會在connect時出錯 提示找不到匹配的connect
class sender {
signals:
     void sigSend( int *msg);
};
正確的做法是
class sender : public QThread{
Q_OBJECT
signals:
     void sigSend( int *msg);
};

繼承任意元數據的派生類都可以

調用流程通常是:

1
2
3
4
5
 實現信號函數  void sigSend( int *msg);
 在某個方法內調用信號  emit sigSend(&a);
 實現槽函數   void slotRecv( int *msg);
 創建對象后  連接信號與槽 connect(sender, SIGNAL(sigSend( int *)), recver, SLOT(slotRecv( int *)));
 在某個地方調用包含觸發信號的方法

元對象系統的構成

  1. QObject為所有需要利用元對象系統的對象提供一個基類。
  2. Q_OBJECT宏,在類的聲明體內激活meta-object功能,比如動態屬性、信號和槽。
  3. Meta Object Compiler(MOC),為每個QObject派生類生成代碼,以支持meta-object功能。
  4. QObject定義了從一個QObject對象訪問meta-object功能的接口,Q_OBJECT宏用來告訴編譯器該類需要激活meta-object功能,編譯器在掃描一個源文件時,如果發現類的聲明中有這個宏,就會生成一些代碼來為支持meta-object功能——主要是生成該類對應MetaObject類以及對QObject的函數override(重載)。

QObject和QMetaObject

QMetaObject包含了QObject的所謂的元數據,也就是QObject信息的一些描述信息:除了類型信息外,還包含QT中特有的signal&slot信息。

virtual QObject::metaObject();

該方法返回一個QObject對應的metaObject對象,如上文所說,如果一個類的聲明中包含了Q_OBJECT宏,編譯器會生成代碼來實現這個類對應的QMetaObject類,並重載QObject::metaObject()方法來返回這個QMetaObject類的實例引用。這樣當通過QObject類型的引用調用metaObejct方法時,返回的是這個引用的所指的真實對象的metaobject。

如果一個類從QObject派生,確沒有聲明Q_OBJECT宏,那么這個類的metaobject對象不會被生成,這樣這個類所聲明的signal slot都不能使用,而這個類實例調用metaObject()返回的就是其父類的metaobject對象,這樣導致的后果就是你從這個類實例獲得的元數據其實都是父類的數據,這顯然給你的代碼埋下隱患。因此如果一個類從QOBject派生,它都應該聲明Q_OBJECT宏,不管這個類有沒有定義signal&slot和Property。

這樣每個QObject類都有一個對應的QMetaObject類,形成一個平行的類型層次。


The Q_OBJECT macro at the beginning of the class definition is necessary for all classes that define signals or slots 只有加入了Q_OBJECT,你才能使用QT中的signal和slot機制。 比如編寫事件接口等程序時,有時會出現如下問題: 在PC端成功編譯,但在開發板端卻顯示錯誤: QObject::connect: No such slot QWidget::*******() QObject::connect: (sender name: 'unnamed') QObject::connect: (receiver name: 'unnamed') 這時候,就必須在頭文件派生類的時候,首先像下面那樣引入Q_OBJECT宏: class MyMainWindow : public QWidget { Q_OBJECT ...... } QT中的moc? moc是QT的預編譯器,用來處理代碼中的slot,signal,emit,Q_OBJECT等。 moc文件是對應的處理代碼,也就是Q_OBJECT宏的實現部分,在官方文檔上有詳細說明,與其文件在同一目錄下。
今天項目不能編譯過去,最后和沒改動的解決方案比較了下發現原來是把Generated MOC Files里面少了兩個moc**_xxx.cpp文件!!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM