在初學Qt的過程中,時不時地要通過F2快捷鍵來查看QT類的定義,發現類定義中有許多Q_PROPERTY的東西,比如最常用的QWidget的類定義:
Qt中的Q_PROPERTY宏在Qt中是很常用的,那么它有什么作用呢?
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])
之前一直在使用VS開發C++程序,接觸過開發Ocx控件會有控件屬性設置,Qt這里的屬性系統可以和之前的知識聯系起來,Qt的屬性功能使得我們可以選擇訪問數據成員的方式,屬性就像是類的數據成員,但是在元對象系統中,它的其他特性是到處可見的(相比較於類成員的一般情況下私有化)。
我們使用這個宏的時候,注意兩個問題:
1)類型,屬性名和READ(讀)方法是必須的。也就是前三個參數可必須有的。類型可以是QVariant支持的任一類型,又或者是我們自定義的類型,其他是可選的。下面的title屬性定義可以這么來說明:定義一個屬性title,類型是QString,讀title的方法是title()函數,寫title的方法是setTitle,這里USER表示是否用戶自定義類型,這里應該設置為false。
2)屬性聲明完了以后,我們還需要進行讀寫函數的聲明和定義
為什么要使用它呢?在哪里使用它呢?
答:Qt中類的屬性是給腳本和元對象系統用的,比如QtScript,QML,或者QObject::property/setProperty……,主要就是用來進行屬性封裝,在具體的腳本,庫,qml開發中必須使用。
最常見的是在QML中訪問C++,通過C++類暴露屬性來使用,接上面實例如下:
1、新建Qt Quick工程:qt PROPERTY
2、新建C++類TestProperty,公有繼承於QObject
3、為TestProperty類設置上述屬性title
Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged);
4、屬性讀寫函數聲明與實現
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
#ifndef
TESTPROPERTY_H #define TESTPROPERTY_H #include <QObject> 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; }; #endif // TESTPROPERTY_H |
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#include
"TestProperty.h"
TestProperty::TestProperty(QObject *parent) : QObject(parent) { } QString TestProperty::title() { return m_title; } void TestProperty::setTitle(QString strTitle) { m_title = strTitle; emit titleChanged(); } |
5、在main函數中注冊這個類,導出到qml中
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#include
<QGuiApplication> #include <QQmlApplicationEngine> #include <qglobal.h> #include "TestProperty.h" int main( int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); qmlRegisterType<TestProperty>( "TestProperty" , 1 , 0 , "TestProperty" ); QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral( "qrc:/main.qml" ))); if (engine.rootObjects().isEmpty()) return - 1 ; return app.exec(); } |
6、在qml中調用title屬性
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
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; } } |
運行后: