天天看點

學習Qt之屬性系統詳解

文章目錄

  • ​​一、屬性系統有什麼用?​​
  • ​​二、屬性詳解​​
  • ​​三、屬性定義​​
  • ​​四、屬性使用​​
  • ​​五、類的附加資訊​​

一、屬性系統有什麼用?

一般我們說一個類有什麼屬性,指的就是這個類有啥成員變量。比如People類中有個int age的私有成員變量,我們就可以說這個People類有個“年齡”屬性可以更改讀取。

Qt提供的屬性系統,作用就是把類的資訊暴露出來成為通用的、大家都認識的資訊。比如用C++語言寫的People類中中有個int age變量,但所如果用QML語言去讀取就會出問題,因為QML有自己的規則,它不認識C++規則。用Qt的屬性系統就可以解決這個問題,當一個類的成員變量或者成員函數用屬性系統處理一下,它們就從C++内部中暴露出來,而且大家都認得。

學習Qt之屬性系統詳解
屬性系統是專門為元對象系統服務

二、屬性詳解

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();​

​、​

​void setFunction(type n);​

​ 指定了MEMBER之後就能再指定READ和WRITE

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();      

繼續閱讀