在初學Qt的過程當中,時不時地要經過F2快捷鍵來查看QT類的定義,發現類定義中有許多Q_PROPERTY的東西,好比最經常使用的QWidget的類定義:函數
Qt中的Q_PROPERTY宏在Qt中是很經常使用的,那麼它有什麼做用呢? ui
Qt提供了一個絕妙的屬性系統,Q_PROPERTY()是一個宏,用來在一個類中聲明一個屬性property,因爲該宏是qt特有的,須要用moc進行編譯,故必須繼承於QObject類。spa
通常咱們說一個類有什麼屬性,指的就是這個類有啥成員變量。好比 People 類中有個 int age 的私有成員變量,咱們就能夠說這個 People 類有個「年齡」屬性能夠更改讀取。3d
Qt 提供的這個屬性系統,做用就是把類的信息暴露出來成爲通用的你們都認識的信息。好比用 C++ 語言寫的People 類中有個 int age 變量,可是若是用 QML 語言去讀取就會出問題,由於 QML 有本身的規則,它不認識 C++ 啊。怎麼辦呢?用 Qt 的屬性系統就能夠解決這個問題。屬性系統能夠這樣理解:當一個類的成員變量或者成員函數用屬性系統處理一下,它們就從 C++ 內部中暴露出來,並且你們都認得。對象
屬性系統是專門爲元對象系統服務的。blog
Q_PROPERTY(type name
READ getFunction
[WRITE setFunction]
[RESET resetFunction]
[NOTIFY notifySignal]
[DESIGNABLE bool]
[SCRIPTABLE bool]
[STORED bool]
[USER bool]
[CONSTANT]
[FINAL])繼承
以前一直在使用VS開發C++程序,接觸過開發Ocx控件會有控件屬性設置,Qt這裏的屬性系統能夠和以前的知識聯繫起來,Qt的屬性功能使得咱們能夠選擇訪問數據成員的方式,屬性就像是類的數據成員,可是在元對象系統中,它的其餘特性是處處可見的(相比較於類成員的通常狀況下私有化)。ip
咱們使用這個宏的時候,注意兩個問題:ci
1)類型,屬性名和READ(讀)方法是必須的。也就是前三個參數可必須有的。類型能夠是QVariant支持的任一類型,又或者是咱們自定義的類型,其餘是可選的。下面的title屬性定義能夠這麼來講明:定義一個屬性title,類型是QString,讀title的方法是title()函數,寫title的方法是setTitle,這裏USER表示是否用戶自定義類型,這裏應該設置爲false。開發
2)屬性聲明完了之後,咱們還須要進行讀寫函數的聲明和定義
爲何要使用它呢?在哪裏使用它呢?
答:Qt中類的屬性是給腳本和元對象系統用的,好比QtScript,QML,或者QObject::property/setProperty……,主要就是用來進行屬性封裝,在具體的腳本,庫,qml開發中必須使用。
最多見的是在QML中訪問C++,經過C++類暴露屬性來使用,接上面實例以下:
一、新建Qt Quick工程:qt PROPERTY
二、新建C++類TestProperty,公有繼承於QObject
三、爲TestProperty類設置上述屬性title
Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged);
四、屬性讀寫函數聲明與實現
class TestProperty : public QObject
{
Q_OBJECT
public:
explicit TestProperty(QObject *parent = nullptr);
Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged);
QString title();
void setTitle(QString strTitle);
signals:
void titleChanged();
public slots:
private:
QString m_title;
};
QString TestProperty::title()
{
return m_title;
}
void TestProperty::setTitle(QString strTitle)
{
m_title = strTitle;
emit titleChanged();
}
五、在main函數中註冊這個類,導出到qml中
#include <qglobal.h>
#include "TestProperty.h"
qmlRegisterType<TestProperty>("TestProperty", 1, 0, "TestProperty");
六、在qml中調用title屬性
import QtQuick 2.9
import QtQuick.Window 2.2
import TestProperty 1.0
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello Qt")
TestProperty{
id: testProperty
title: qsTr("Hello World")
}
Component.onCompleted: {
title = testProperty.title;
}
}
運行後: