Qt之Q_PROPERTY宏理解


在初學Qt的過程中,時不時地要通過F2快捷鍵來查看QT類的定義,發現類定義中有許多Q_PROPERTY的東西,比如最常用的QWidget的類定義:

Qt中的Q_PROPERTY宏在Qt中是很常用的,那么它有什么作用呢?  

Qt提供了一個絕妙的屬性系統,Q_PROPERTY()是一個宏,用來在一個類中聲明一個屬性property,由於該宏是qt特有的,需要用moc進行編譯,故必須繼承於QObject類。

如何理解“屬性系統”這個概念?

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

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

屬性系統是專門為元對象系統服務的。

 

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、屬性讀寫函數聲明與實現

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

}

5、在main函數中注冊這個類,導出到qml中

#include <qglobal.h>

#include "TestProperty.h"

                         

qmlRegisterType<TestProperty>("TestProperty", 1, 0, "TestProperty");

 

6、在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;
    }
}

運行后:

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM