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"10"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;
    }
}

运行后:

 

posted on 2019-05-05 16:42  我来乔23  阅读(22908)  评论(3编辑  收藏  举报

导航