1. Q_PROPERTY
Qt提供了一個絕妙的屬性系統,Q_PROPERTY()是一個宏,用來在一個類中聲明一個屬性property,由於該宏是qt特有的,需要用moc進行編譯,故必須繼承於QObject類。
Q_PROPERTY(type name
READ getFunction
[WRITE setFunction]
[RESET resetFunction]
[NOTIFY notifySignal]
[DESIGNABLE bool]
[SCRIPTABLE bool]
[STORED bool]
[USER bool]
[CONSTANT]
[FINAL])
Qt的屬性功能使得我們可以選擇訪問數據成員的方式,屬性就像是類的數據成員,但是在元對象系統中,它的其他特性是到處可見的(相比較於類成員的一般情況下私有化)
我們使用這個宏的時候,注意兩個問題:
1)類型,屬性名和READ(讀)方法是必須的。也就是前三個參數可必須有的。類型可以是QVariant支持的任一類型,又或者是我們自定義的類型,其他是可選的。下面的title屬性定義可以這么來說明:定義一個屬性title,類型是QString,讀title的方法是title()函數,寫title的方法是setTitle,這里USER表示是否用戶自定義類型,這里應該設置為false。
Q_PROPERTY(QString title READ title WRITE setTitle USER true);
2)屬性聲明完了以后,我們還需要進行讀寫函數的聲明和定義
下面是一些典型的聲明屬性的示例:
Q_PROPERTY(double minValue READ getMinValue WRITE setMinValue)
Q_PROPERTY(bool animation READ getAnimation WRITE setAnimation)
Q_PROPERTY(QColor barColor READ getBarColor WRITE setBarColor)
- 一個屬性的行為就像類的數據成員,但是它還具有附加的特性,這些特性可以被元數據對象系統操作。這些特性是:
需要一個READ訪問器函數。用於讀屬性的值。理想情況下,有一個不變的函數用於此目的,並且它必須返回屬性的類型的值或指針或引用。例如,QWidget::focus是一個只讀的屬性,它對應一個讀函數:QWidget::hasFocus()。 - 一個可選的WRITE訪問器函數。它用於設置屬性的值。它必須返回空並且至少具有一個參數,參數是屬性類型的值或指針或引用。例如:QWidget::enabled具有WRITE函數QWidget::setEnable()。只讀屬性不需要寫函數。例如,QWidget::focus沒有對應的寫函數。
- 一個可選的RESET函數。用於設置屬性的值到它的默認值。例如:QWidget::cursor具有典型的READ和WRITE函數,QWidget::cursor()和QWidget::setCursor(),並且它也具有一個RESET函數,QWidget::unsetCursor()。RESET函數必須返回void並且不帶有任何參數。
- 一個可選的NOTIFY信號。如果被定義了,信號將在屬性的值改變時發出。信號必須帶有一個參數,這個參數的類型必須與屬性相同;參數保存的是屬性的新值。
- 一個DESIGNABLE變量表明此屬性是否在界面設計器的屬性編輯器中出現。大多數屬性是可見的,除了為這個變量傳入true或false,你還可以指定一個bool型的成員函數。
- SCRIPTABLE變量表明這個屬性是否可以被一個腳本引擎操作(默認是true)。你也可以賦予它true或false或bool型函數。
- STORED變量表明了屬性是否被認為是獨立存在還是依賴於其它的值而存在。它也表明是否在保存對象狀態時保存此屬性的值。大多數屬性都是需要保存的,但是,如QWidget::minimumWidth()就是不被保存的,因為它的值是從另一個屬性QWidget::minimumSize()得來的。
- USER變量表明屬性是否被設計為面向用戶的或用戶可修改的類屬性。通常,每個類只有一個USER屬性。例如,QAbstractButton::checked是按鈕類的用戶可修改屬性。注意QItemDelegate獲取和設置widget的USER屬性。
- CONSTANT的出現表明屬性的值是不變的。對於一個object實例,常量屬性的READ方法在每次被調用時必須返回相同的值。此常量值可能在不同的object實例中不相同。一個常量屬性不能具有WRITE方法或NOYIFY信號。
- FINAL變量的出現表明屬性不能被派生類所重寫。有些情況下,這可以用於效率優化,但不是被moc強制的。程序員必須永遠注意不能重寫一個FINAL屬性。