文章目錄
- 一、屬性系統有什麼用?
- 二、屬性詳解
- 三、屬性定義
- 四、屬性使用
- 五、類的附加資訊
一、屬性系統有什麼用?
一般我們說一個類有什麼屬性,指的就是這個類有啥成員變量。比如People類中有個int age的私有成員變量,我們就可以說這個People類有個“年齡”屬性可以更改讀取。
Qt提供的屬性系統,作用就是把類的資訊暴露出來成為通用的、大家都認識的資訊。比如用C++語言寫的People類中中有個int age變量,但所如果用QML語言去讀取就會出問題,因為QML有自己的規則,它不認識C++規則。用Qt的屬性系統就可以解決這個問題,當一個類的成員變量或者成員函數用屬性系統處理一下,它們就從C++内部中暴露出來,而且大家都認得。

屬性系統是專門為元對象系統服務
二、屬性詳解
Qt提供一個
Q_PROPERTY()
宏可以定義屬性,它也是基于元對象系統實作的。Qt的屬性系統與C++編譯器無關,可以用任何标準的C++編譯器編譯定義了屬性的Qt C++程式。
在QObject的子類中,用宏
Q_PROPERTY()
定義屬性,其使用格式如下:
Q_PROPERTY(type name (READ getFunction [WRITE setFunction] | MEMBER memberName [(READ getFunction | WRITE setFunction)])
[RESET resetFunction]
[NOTIFY int]
[REVISION int]
[DESIGNABLE bool]
[SCRIPTABLE bool]
[STORED bool]
[USER bool]
[CONSTANT]
[FINAL])
注意:
getFunction的傳回值類型必須為type;
setFunction的傳回值必須為空,而且必須帶一個參數
例如:
、
type getFunction();
指定了MEMBER之後就能再指定READ和WRITE
void setFunction(type n);
Q_PROPERTY()宏定義一個傳回值類型為type,名稱為name的屬性,用READ、WRITE關鍵字定義屬性的讀取、寫入函數,還有其他的一些關鍵字定義屬性的一些操作特性。屬性的類型可以是QVarient支援的任何類型,也可以使用者自定義類型。
Q_PROPERTY()宏定義屬性的一些關鍵字的意義如下:
- READ:指定一個讀取屬性值的函數,沒有MEMBER關鍵字必須設定READ。
- WRITE:指定一個設定屬性值的函數,隻讀屬性沒有WRITE設定。
- MEMBER:指定一個成員變量與屬性關聯,成為可讀科協的屬性,無需再設定READ和WRITE。
- RESET:可選,用于指定一個設定屬性預設值的函數。
- NOTIFY:可選,用于設定一個信号,當屬性值變化時發射此信号。
- DESIGNABLE:表示屬性是否在Qt Dseigner裡可見,預設為true。
- CONSTANT:表示屬性值是一個常數,對于一個對象示例,READ指定的函數傳回值是常數,但是每個執行個體的傳回值可以不一樣。具體CONSTANT關鍵字的屬性不能有WRITE和NOTIFY關鍵字。
- FINAL:表示所定義的屬性不能被子類重載。
三、屬性定義
1. READ和WRITE
//頭檔案
Class Widget : public QObject
{
Q_PROPERTY(int age READ readAge WRITE setAge)
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
int my_age;
int readAge();
void setAge(int n);
}
//源檔案
int Widget::readAge()
{
return my_age;
}
void Widget::setAge(int n)
{
my_age = n;
}
2. MEMBER
//頭檔案
Class Widget : public QObject
{
Q_PROPERTY(int age MEMBER my_age NOTIFY ageChanged)
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
int my_age;
int readAge();
void setAge(int n);
signal:
void ageChanged();
}
//源檔案
int Widget::readAge()
{
return my_age;
}
void Widget::setAge(int n)
{
my_age = n;
}
四、屬性使用
如果是用READ、WRITE,直接調用指定的函數即可,例如:
Widget *w = new Widget;
w->setAge(true);
如果是用MEMBER,那麼用QObject的
property()
和
setProperty()
兩個函數,如:
Widget *w = new Widget;
w->property("age");
w->setProperty("age",18);
五、類的附加資訊
//頭檔案
Class Widget : public QObject
{
Q_CLASSINFO("author","Wang")
Q_CLASSINFO("version","3.0.1")
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
}
//使用
Widget *w = new Widget;
w->metaObject()->classInfo(0).name();
w->metaObject()->classInfo(0).value();
w->metaObject()->classInfo(1).name();
w->metaObject()->classInfo(1).value();