QT之Qt之Q_PROPERTY宏理解


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

 TestProperty.h 
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
       

TestProperty.cpp
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中

main.cpp
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屬性

 main.qml
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;
    }
}

運行后:

 


免責聲明!

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



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